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

If --cert-email is provided, --cert-oidc-provider should be required (verification) #1947

Closed
znewman01 opened this issue Jun 2, 2022 · 12 comments
Labels
bug Something isn't working

Comments

@znewman01
Copy link
Contributor

I frequently see a misconception that the --cert-email is sufficient to verify the authenticity of an artifact. However, it's possible that some crappy OIDC provider issues OIDC tokens containing any email—and that's okay!. The only thing that a Fulcio certificate attests to is: "at this time, a successful OIDC authentication to Sigstore happened, and here are the details." It doesn't claim "the party to whom I issued this certificate is in control of the email address in the certificate."

So if a client wants to check that a certificate was issued to a particular party, they should be required to specify according to whom.

^ To be clear, the above is largely opinion but I am willing to fight you about it

CC @haydentherapper who agrees IIRC

@znewman01 znewman01 added the bug Something isn't working label Jun 2, 2022
@vaikas
Copy link
Contributor

vaikas commented Jun 2, 2022

In lock step with this, we should make sure that policy-controller also behaves identically. For example here:
https://github.com/sigstore/cosign/blob/main/pkg/apis/policy/v1beta1/clusterimagepolicy_types.go#L182

We should then enforce that you must specify both Issuer and Subject.

@woodruffw
Copy link
Member

I frequently see a misconception that the --cert-email is sufficient to verify the authenticity of an artifact. However, it's possible that some crappy OIDC provider issues OIDC tokens containing any email—and that's okay!

The only thing I'll argue with is the "okay" part 🙂 -- IMO, it's not "okay" until there's a clearer (and public) threat model explaining what verification actually means. My intuition (which was apparently wrong!) was that verification implies either strong ownership or strong attestation for an email or other identity, i.e. that the OIDC provider performed their own verification for that identity. My intuition was then that Sigstore "guaranteed" that property by only trusting a handful of "high-quality" OIDC providers that actually preserve that property, e.g. Google, MS, and GitHub.

(Overall, I agree with you, if the goal is to eventually support "crappy" OIDC providers. And maybe it is! But then we should be as explicit as possible that the "identity" notion we use is "identity modulo consumer-trusted provider," not "identity.")

@znewman01
Copy link
Contributor Author

IMO, it's not "okay" until there's a clearer (and public) threat model explaining what verification actually means.

Yes, this is a great point. We need to be crystal-clear on the semantics of whatever we're trying to provide.

My intuition (which was apparently wrong!) was that verification implies either strong ownership or strong attestation for an email or other identity, i.e. that the OIDC provider performed their own verification for that identity.

Your intuition is currently correct! At this moment, we are only planning to support OIDC providers that meet a list of requirements like what you're describing: sigstore/fulcio#397

I personally have an outlook that I call "Fulcio maximalism": I want to minimize what we're claiming when Fulcio issues a certificate: it is not true that something is secure because it is signed with a certificate that's in Fulcio, or because its signature is Rekor. But these certs/signatures, in combination with well-designed policies, can help verify artifacts.

Then, we are free to add any OIDC provider we want (the "maximal" part). (We definitely have to do that in the order of (1) set expectations, and (2) relax entry criteria).

Again, disclaimer: this is purely personal opinion.

@haydentherapper
Copy link
Contributor

My intuition was then that Sigstore "guaranteed" that property by only trusting a handful of "high-quality" OIDC providers that actually preserve that property, e.g. Google, MS, and GitHub.

Yep, that is correct! And I actually just updated the list Zach included to mention that OIDC providers we allow should enforce an email challenge. But maybe a bug happens and it doesn't challenge ownership. Maybe there's some sequence of steps of account creation that can bypass the challenge.

At this very moment, we don't have to require both flags, there's not an immediate risk due to how the production environment (Fulcio/Dex) is set up. I think we do need to encourage proper practices though. If we don't, and one day we add an OIDC provider that doesn't appropriately challenge email ownership, then we have at best a breaking change for clients (who will need to check both) or at worst a CVE.

If we enforce both now(-ish), then we start pushing verification in the right direction. There's some UX questions around how to know what the right issuer is that we'll need to figure out first.

Addendum (and a TODO for me to go investigate): I added a username issuer type to Fulcio for those who run their own OIDC providers but don't run their own mail server - The SAN for username-bound certificates will be email:username@issuer.com. Let's say you sign up for a Google account with a service that does run its own mail server, example.com. When Fulcio issued a certificate, its email SAN will be id@example.com, and its issuer will be accounts.google.com. Now, let's say example.com starts running its own IDP that issues tokens with only usernames, and the IDP is added to Fulcio. Now, when Fulcio issued a certificate for this IDP, the SAN will be id@example.com, and the issuer will be example.com. This is a little bit weird, because those identities may not be the same. There's a different threat model for each issuer type. This is another argument for requiring both email and oidc provider flags, but I also want to go see if there's a better way to represent a username identity with x.509.

@nealmcb
Copy link
Contributor

nealmcb commented Jun 2, 2022

Ouch - good points.

Is it really the case that all three current Fulcio IdPs can vouch for arbitrary domains? GitHub, Google, and maybe Microsoft also?

I'd think we don't want a threat model (for use of a naked email address as id) which would forever be just as awful as it is with the current global CA debacle, where everyone is vulnerable to attacks not just on the signer's chosen email provider, but also all IdPs.

I think identities should be first-class objects, perhaps using some of the W3C approaches I've briefly noticed. I for one don't want to have to be vulnerable to repos, or who they say is authorized to produce an artifact, either. Isn't that one reason that PyPI is trying to leverage this work - to protect from a PyPI breach?

And imagining that people or relying parties will move (email, IdP) pairs around, half of which is familiar and half of which is obscure and nearly arbitrary, seems unreasonable.

So would it make sense to eliminate use of email addresses as ids, and switch to Decentralized Identifiers (DIDs) like SCITT apparently does? Something that people don't think they can muck with. And thus do away with use of naked email addresses or separate options like --cert-email?

@haydentherapper
Copy link
Contributor

@znewman01 wrote about DIDs in https://blog.sigstore.dev/privacy-in-sigstore-57cac15af0d0

It's something we could consider at some point, but for ease of use with the current infrastructure, OIDC is the best that we've got currently.

@woodruffw
Copy link
Member

Is it really the case that all three current Fulcio IdPs can vouch for arbitrary domains? GitHub, Google, and maybe Microsoft also?

Google and MS are able to, for sure. I'm not sure about GitHub -- I think it can in the sense that it can generate OIDC tokens for the "primary" email address registered to the account, but the UX there is poor (users with professional/individual splits...)

My 0.02c regarding the threat model: I'd personally like an ecosystem where anybody can assert that I've signed for an artifact with just my email address, my GitHub handle, or the repository slug + release tag. That requires a certain amount of IdP quality control (or maybe not, if we can establish some kind of "quality" policy/allowlist?), and IMO the transitive trust that comes with that is reasonable (a breach in Google or MS's OIDC provider would be far more catastrophic than just sigstore). But to get there, we have to draw the line around what sigstore will not protect against 🙂

@znewman01
Copy link
Contributor Author

I think there are a few key points that we agree on, and a few points of departure. Give me a little bit of time and I'll try to articulate those and possible paths forward. But for now, a tangent:

I for one don't want to have to be vulnerable to repos, or who they say is authorized to produce an artifact, either. Isn't that one reason that PyPI is trying to leverage this work - to protect from a PyPI breach?

Not in-scope for this issue, but lots of interesting discussion here. This document, in particular the "Associating identities with packages" section, goes into some options. If you're curious, the OpenSSF has a "Securing Software Repos" working group that will be of interest (they communicate largely in the OpenSSF Slack, and meet every couple of weeks). There are a few other references that we can dig up if you ask in one of those venues.

@znewman01
Copy link
Contributor Author

Okay, so some points of agreement:

  • At the moment, an email address in a SAN is a "pretty good but not incontrovertible" demonstration of control of that email address: the IdPs supported in Fulcio all verify the emails that they pass along.
  • At the moment, there is no one "canonical" IdP for a given email identity and, in fact, any of the IdPs we currently have can attest to any email address.
  • We should create standards (and document them well) for what IdPs we will accept in the public good instance of Fulcio: Designing list of requirements for new IDPs for public good deployment fulcio#397
  • People are probably not able to meaningfully distinguish between "user@gmail.com, as attested to by Google" and "user@gmail.com, as attested to by Microsoft", but computers should have no problem with this.
  • The status quo is confusing: when explaining the notion of identity in Sigstore, we have not been clear about what identities we mean. The --cert-email flag is poorly named.

The points of disagreement:

  • How likely is it that people will directly engage with Sigstore identities while setting verification policies?

    • The use cases that I consider mostly involve (1) client software that has policies, or the means of determining policies from other sources, embedded in it, and (2) explicit policies that are distributed manually. This includes package repositories, an enterprise with a Sigstore controller.
    • I am of the opinion that any security measures that rely on users to look at Sigstore identities and guess whether these identities should be trusted is unreliable. Heuristics like "ahh, this is from user@example.com, I think I've heard of them, it's probably safe" are bad. My computer getting a policy from a trusted location and checking it for me is good.
  • What does/should a Fulcio certificate actually attest to?

    1. (my view) at time T, a client presented Fulcio with a valid token from IdP Iss with subject S (in the Iss world only).
    2. At time T, a client demonstrated control of this "email identity" to Fulcio (via IdP Iss, but that's unimportant).
    3. At time T, a client demonstrated control of this "email identity" to Fulcio via its "canonical IdP."

    Certainly, (1) is true. (2) is mostly true *for the time being. (3) could be true long-term (see below for more exploration). The argument for (1) might be "advertising the bare minimum in terms of what does a Fulcio certificate mean" prevents a "leaky security abstraction." Users can build meaningful higher-level policies on top of Sigstore. The argument for (2) might be "in a tightly controlled Fulcio deployment, we can present a simpler story to users." The argument for (3) might be "it's very confusing and dangerous that a single email can be attested to by multiple IdPs; we should only allow the 'correct' IdP to do this."

    I think there are merits to all of the above viewpoints, and that @woodruffw articulates why it's important to nail this down:

    we have to draw the line around what sigstore will not protect against 🙂

  • Should we try to have a canonical identity provider for each email address?

    • There is a big advantage, in that there's a simple-to-explain (but complicated-to-grok) story about what an identity is. People see an email, and assume that it corresponds to a single person/entity who owns that email.
    • I believe that this would be an unrealistic amount of work, because we'd have to come up with a way of advertising the canonical OIDC provider, standardize it, and get every domain in the world to pick a canonical IdP and publish it using that method.
    • Further, I don't want to promote "emails" as the main notion of identity to the exclusion of other methods. I think a diversity of types of identity is actually really good.
    • This world doesn't allow for "multi-vantage-point" verification of an email identity—with overlapping IdPs, I can say something like "I believe software package X is legitimate if the accounts (user@example.com via Google) and (user@example.com via GitHub) have both signed it" for extra assurance.

Okay, so where do we go from here? As I expected, this is a pretty contentious topic. It's definitely turning out to be bigger than a change to the behavior of one particular flag in cosign. So here's my proposal:

  1. I'd like to table higher-level arguments on this issue, because Cosign doesn't seem to be the right place. I've opened What does the email in a Fulcio certificate mean? fulcio#639, which is a somewhat more appropriate forum.
  2. I feel relatively confident in my beliefs here, so I'd like to consolidate them. It will probably take me a week or so, but I can write a document for public critique.
  3. I am personally not interested in the "canonical per-domain IdP," so I will not invest a lot of effort in design there. But I bet that the community would enjoy reading a proposal for how such a thing would work.

@woodruffw
Copy link
Member

That's a really excellent summary, thank you!

How likely is it that people will directly engage with Sigstore identities while setting verification policies?

Yeah, we need to hammer this out. Here's a use case that I'd like to pursue in PyPI: once we get more people signing their releases with sigstore, I'd like to be able to add a "trusted signature" doohicky to the UI that roughly corresponds to one of the following:

  1. The release file(s) were all signed using an email identity, and that identity matches the package's metadata (or perhaps one of the emails linked to the PyP account)
    • Thinking about it more, it probably has to be the package metadata, to prevent changes to a project's maintainers from invalidating previous releases.
  2. The release file(s) were all signed using an OIDC identity from a GitHub workflow (or other CI provider), and that token's claims (repository + tag) match the package's metadata (repository URL + version)

In the above scenario, people aren't doing very much interaction -- they're only visually scanning information that PyPI is monitoring and providing. I believe our plan is to ultimately do something similar for pip itself as well, which will similarly (hopefully) involve a minimum amount of human interaction and will take either route (1) or (2) above.

  • I am of the opinion that any security measures that rely on users to look at Sigstore identities and guess whether these identities should be trusted is unreliable. Heuristics like "ahh, this is from user@example.com, I think I've heard of them, it's probably safe" are bad. My computer getting a policy from a trusted location and checking it for me is good.

Strong agree. I think we probably want to discourage people from just visually scanning emails (or other identities) and then manually confirming that the identity has done something resembling the signing they're expecting. They should be visually scanning a product of verification (modulo a policy, like above) instead.

What does/should a Fulcio certificate actually attest to?

No surprise, but I lean towards (ii) 🙂. In terms of the things that I'd like to apply Fulcio and Sigstore towards, which IdP performed the proof isn't too important as long as all of them as considered "reliable." For better or worst, I believe this comports with the average end-user's intuition for what Fulcio is really "doing" when it issues a cert for an email identity. Without that reliable/"high-quality" guarantee, it's less clear to me (although this may be a lack of understanding on my part!) what sigstore's security proposition to the broader packaging ecosystem is -- it's easy to see a scenario in which verification against the CT log is "diluted" or otherwise impaired because implementers don't know what constitutes a reasonable policy for their use case. I think we can foresee that use case and resultant policy for them, and potentially save them some hard mistakes in the future.

Should we try to have a canonical identity provider for each email address?

IMO, no, at least not until we flesh out why this might be a desirable property.

For my part, I actually think that having third-party IdPs for an email identity can make explaining emails-as-identities a little easier to less technical folks: there's an intuitive sense in which multiple potential verifiers for a single email address actually strengthen the impression that a particular identity is real. As a contrived example: my nontechnical parents might not fully grok what it means for sigstore-enthusiast@gmail.com to be attested for by Google, but attested for by Microsoft makes a little more sense (they understand the concept of signing up for a different service using one's email, and how this amounts to a proof of access to the email.)

On the security/threat model side, I'm weakly confident that supporting multiple high-quality IdPs for a single identity does not pose a significant risk separate from the already latent risk of IdP compromise. I actually think there are security wins to be had in not trying to restrict the IdP to the "canonical" one for the identity: attempting to do so means inviting the possibility of exploitable confusion around IdP changes (e.g. custom email domain, but change in mail provider) and additional ecosystem configuration (making people configure their intended IdP via yet another DNS record or similar means?)

(I strongly agree with the remaining points about not trying to determine a canonical IdP for each email!)

Sounds good to me! We can continue there; I'll post this on the issue just to tie a knot around my part of the conversation 🙂

(Once again: thank you for doing this excellent summary, and continuing to push this on! I'm very excited to hammer out Sigstore's (and Fulcio's) threat model, and this is a critical part of doing so.)

@di
Copy link
Member

di commented Nov 23, 2022

FWIW, the latest release of sigstore-python now requires --cert-identity and --cert-oidc-issuer at verification time.

haydentherapper added a commit to haydentherapper/website that referenced this issue Dec 13, 2022
Verification of the identity of the signer is a critical part of Sigstore verification. Otherwise, you are only verifying that there is some signature that is valid, instead of checking that the signature was generated by someone you trust.

For more information, sigstore/cosign#2056 contains some discussion around why we want to require these flags, and sigstore/cosign#1947 for why we require both of these flags.

An open question for you is if this specified identity (which came from the certificate) will change between releases. If so, how would you like users to know which identity signed a release?
@haydentherapper
Copy link
Contributor

@znewman01 Closing since #2056 is completed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants