Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trusting multiple TUF repositories #11

Open
haydentherapper opened this issue Oct 26, 2023 · 7 comments
Open

Trusting multiple TUF repositories #11

haydentherapper opened this issue Oct 26, 2023 · 7 comments
Labels
enhancement New feature or request

Comments

@haydentherapper
Copy link
Contributor

Description

I've been thinking about private deployments in which consumers will trust artifacts signed in both their private environment and from the public good instance. Currently, clients are configured to trust a single TUF repository. The UX is not ideal in that clients will have to reinitialize their TUF metadata before verifying artifacts signed with each infrastructure. Furthermore, if an artifact relies on multiple TUF environments to be verified, it is not currently possible (I believe, let me know if I'm wrong) to verify the artifact. This could occur for example if an artifact is signed with public Fulcio and recorded to public Rekor, but uses a private timestamp authority.

What should the user experience look like in this case? For Cosign, TUF metadata is either trusted explicitly with an initialize command, or on-demand assuming the TUF metadata can be verified with the baked-in TUF root. I'm not sure how other clients allow custom roots to be specified. I would propose explicit initialization with multiple trusted TUF roots. Maybe an option to say "trust this set of roots + the baked-in root"?

How should verification handle targets across multiple TUF repos? Should a client explicitly state if they want to be able to verify using targets across both (like the example case I gave)? Or should it be implicit after initialization with multiple TUF roots?

Any other concerns to think through?

cc @kommendorkapten @woodruffw @loosebazooka @bdehamer @jku @steiza for thoughts

@haydentherapper haydentherapper added the enhancement New feature or request label Oct 26, 2023
@mnm678
Copy link

mnm678 commented Oct 26, 2023

I'd recommend taking a look at TAP 4. The automotive variant of TUF uses two TUF repositories, with consensus between them before updates are installed. The scenario here is a bit different, where different responsibilities need to be assigned to each TUF repository. The map file proposed in TAP 4 also allows for this type of assignment to different repositories. Basically the map file could say: use the public TUF root for Fulcio and the private root for timestamping.

@loosebazooka
Copy link
Member

loosebazooka commented Oct 26, 2023

We use the trusted-root.json to define what the "current" rekor and fulcio instances are for signing. As long as we can define "current", we should be good. Otherwise we probably have to re-define how we select infrastructure at signing.

For verification I think "current" matters less, although you might want to define boundaries to prevent some sort of squatting that might occur when conflicts happen between internal and external repositories? (defining these boundaries is somewhat susceptible to human error)

@steiza
Copy link
Member

steiza commented Oct 26, 2023

The TUF repository here is sort of a proxy for "how do I get the trusted_root.json to verify this artifact?"

I think clients should use the narrowest possible trusted_root.json to verify an artifact. If a system includes a mix of things signed with public good infrastructure and private infrastructure, the system should keep track of which is which so it can provide the narrowest possible information to the verifier.

Clients should support mutually exclusive options to:

  • Specifying a TUF repository (default to public good)
  • Accept a custom trusted_root.json

Most of the time, people will default to public good (or the TUF repository for their private deployment). If they don't have a TUF repository for their private deployment, or if they have some weird hybrid case, they can construct their own trusted_root.json.

For the proposed use-case of public good plus a private timestamp authority, they can use their own TUF client to get the public good trusted_root.json, get the information for their private timestamp authority however they'd like, and construct a custom trusted_root.json to then supply to the verifier.

@haydentherapper
Copy link
Contributor Author

haydentherapper commented Oct 26, 2023

That's reasonable to recommend constructing their own trusted_root.json. I do think that would be a barrier to entry though, as it would require maintaining their own TUF repository to ship trusted_root.json and handling root signing key management.

@mnm678 I've seen TAP4 before, I think that would be great to explore here.

That's a good point around selecting "current" for signing, you'd need some UX around selecting which instance is trusted for signing. This issue really only makes sense for the verification flows now that I think about it.

@kommendorkapten
Copy link
Member

Last summer we did look into TAP-4, but we never went ahead and implement anything. See this doc

One caveat with TAP-4 used in this way is that shadowing can occur (I believe TAP-4 is mostly used to gather consensus between repositories, or using different repositories for different purposes as @mnm678 mentions).

If two repositories "public good" and "internal" both exposes a target trusted_root.json, that target can only be retrieved from one repository, the search order is specified in the file map.json. To circumvent this, one could require (globally) unique naming of the files, which may be hard in practice.

All in all I agree with @steiza here. I believe a user has to be explicit about what they are trusting when verifying.

Specifying a TUF repository (default to public good)

Even without TAP-4 a client could be aware of multiple TUF repositories, and via a flag/parameter chose which one to use. I think this is a simple solution (just be aware that for caching of metadata (and possibly targets) has to be separated, e.g. each metadata in a directory named by the FQDN to the repo or so.

@trishankatdatadog
Copy link

trishankatdatadog commented Oct 27, 2023

Interesting issue. All in all, I will say that whatever solution is chosen here, it should avoid the usual footguns (e.g., dependency confusion). Perhaps the best place to begin is by eliciting and enumerating use cases 🙂

@jku
Copy link
Member

jku commented Oct 28, 2023

I think it is useful for this discussion to happen without any reference to TUF -- I believe talking about specific TAPs etc railroads the discussion in harmful ways.

Assuming trusted_root.json defines the source of truth for a client:

  • what does it mean to have multiple sources of truth? What are some specific use cases?
  • How would sigstore like to expose this to users (or system maintainers): how do you identify, add or remove a "source of truth"? Is it useful to have multiple source of truth "active" at the same time? are they ordered?
  • when verifying, do they all sources of truth need to agree, or is it enough for one to do so?
  • What about signing? Is there just one source of truth that is used?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

7 participants