sigstore / fulcio

Sigstore OIDC PKI
Apache License 2.0
643 stars 136 forks source link

What does the email in a Fulcio certificate mean? #639

Open znewman01 opened 2 years ago

znewman01 commented 2 years ago

It's becoming clear that we're not telling a consistent story about "Fulcio identities." I filed https://github.com/sigstore/cosign/issues/1947 to address the fact that I've seen a number of instances where users recommended passing the --cert-email flag to Cosign without checking the issuer. Because there's overlap in the email subjects that different Fulcio IdPs issue tokens for (that is, Google and Microsoft will both give you a token for user@example.com), this gives you least-common-denominator security for a policy that only checks emails: if I made my Microsoft account 10 years ago to play Xbox and with password "ZackPwnsN00bs" and no 2FA, someone can compromise that account and publish artifacts that are trusted in the same manner as if they compromised my Google account with 2FA. That's clearly a bad idea, and I believe that it's due to a lack of clarity as to what a Fulcio certificate means.

For instance, everything seems more consistent if we don't use emails everywhere, and instead use usernames. Then, it's really obvious that "znewman01 via Microsoft" isn't necessarily the same entity as "znewman01 via GitHub." I'm not necessarily advocating for this change, but that seems to be closer to what's happening conceptually right now.

However, the documentation for the project doesn't reflect that: the README currently says that Fulcio "issu[es] certificates based on an OIDC email address." security-model.md says "Fulcio assumes that a valid OIDC token is a sufficient 'proof of ownership' of an email address." I believe that the stress on email suggests something very different than what it is actually happening. I could have made a Microsoft account with an email 10 years ago, then lost that email, but still remember my password—I'm just demonstrating control of the Microsoft account, not the email. Similarly, this relies on every OIDC provider to maintain a certain standard of email verification.

I believe that we should have guidance on the following:

Then, once we have that clarified, we should:

Related reading:

haydentherapper commented 2 years ago

I don't see much difference between a certificate for the email "user@microsoft.com" and a certificate for the username "user" from Microsoft. In both cases, you need to be aware of the issuer vouching for that identity. We can treat email like a username - It's just a value associated with an issuer.

To me, a Fulcio certificate attests to the following:

By the properties of the current providers, we also have confidence that the caller was in control over their email, though replay is something to consider. I don't think Fulcio is attesting to that directly, it's a property of the IDP.

Besides documentation, I'm not convinced there's anything to change in Fulcio's API. It simply unwraps an identity token, extracts useful claims, and wraps those up in a signed blob (with auditable transparency). It's up to the client to verify the contents of the certificate. This is very similar to WebPKI, the difference being it's not just DNS that can be used as an identity proof, it's the pair of identity+issuer.

znewman01 commented 2 years ago

Besides documentation, I'm not convinced there's anything to change in Fulcio's API.

How about in https://github.com/sigstore/sigstore or https://github.com/sigstore/cosign ? I don't have concrete proposals, but I have a hunch that it's possible to create interfaces to the Sigstore verification code that makes expressing sensible verification policies easy, and less-sensible ones hard.

haydentherapper commented 2 years ago

I'm a huge fan of pushing verification logic into sigstore/sigstore. I'm quite concerned that as we build more clients, even with robust client conformance testing, there will be subtle verification flaws between each of the clients. If clients can depend on sigstore/sigstore instead of trying to re-interpret what Cosign does, there will be consistency.

There's a larger conversation that pops up periodically around Cosign-as-a-library - I'd love to move lots of logic out of Cosign into sigstore/sigstore, but there is still a question of how to have conformance between different languages. Should we provide wrappers around sigstore?

nsmith5 commented 2 years ago

I agree we could use a good hard-to-mess-up interface to verification, but I don't think that is a concern of Fulcio. Like @haydentherapper said, the CA is very transparent about what it did. The subject and issuer details are embedded into each certificate and can be used to create good policy, but Fulcio as a service or library isn't really in a great position to dictate that policy or verification interface. I think sigstore/sigstore feel like the right home

woodruffw commented 2 years ago

if I made my Microsoft account 10 years ago to play Xbox and with password "ZackPwnsN00bs" and no 2FA, someone can compromise that account and publish artifacts that are trusted in the same manner as if they compromised my Google account with 2FA. That's clearly a bad idea, and I believe that it's due to a lack of clarity as to what a Fulcio certificate means.

Sorry for the late follow-up, but this completely refutes my claim about multiple IdPs not resulting in a weaker threat model in https://github.com/sigstore/cosign/issues/1947#issuecomment-1146536741 -- thanks for providing it!

This is a really bad problem to have -- my intuition as an end user is that an attestation from a "high-quality" IdP for example@example.com is (almost) as good as a direct login by that identity, not the weakest/oldest credential accepted by any IdP. Then again, I guess there's nothing stopping me from having a similarly terrible password on my email identity itself, so maybe it's the kind of thing that just needs to be documented in the threat model and not "fixed" per se.

haydentherapper commented 2 years ago

I don't know the best issue to ask this on, but to avoid creating another issue, I'll just throw this question here:

Should we recommend against users signing artifacts released on a platform with the same identity as the platform's identity? As in, if I release my artifacts via GitHub, should I use a different identity provider than GitHub to sign artifacts? This reduces the risk associated with a compromised identity. If an attacker can compromise a GitHub identity, ideally they would either only be able to generate signatures for artifacts released outside of GitHub (and so would need to compromise the package repository account too for a full compromise), or tamper with the artifacts released via GitHub (and so would need to compromise the user's signing identity too for a full compromise).

A similar version of this question came up when discussing if package repositories should operate IDPs. However, given we currently support GitHub as an IDP, this is more pressing to decide if we want to give guidance around this.

@znewman01

znewman01 commented 2 years ago

Good question.

I think this is starting to get somewhat out-of-scope for Sigstore itself, because it really depends on your threat model. Further, this is really a matter for whatever tools is enforcing policy, not the Sigstore infra itself. That said, I think there's a place for us to provide suggested usage patterns and mention trade-offs.

For GitHub specifically, I think the question is ill-defined. What releases are being distributed via GitHub, and how are verifiers checking that they're legitimate?

Broadly, I think diversification is better when "X AND Y" need to be compromised, and worse when "X OR Y" need to be compromised. This feels like the former scenario, and I think in general that's right. I don't think we'd go wrong by pushing users in that direction, but I'd prefer to address it more systemically (e.g., at a policy enforcement tool, or in a package manager).

haydentherapper commented 2 years ago

I'm wondering if this should be part of the client specification in the architecture docs - Recommended but not enforced behavior. Or maybe a section on recommended policy?

For GitHub specifically, I think the question is ill-defined. What releases are being distributed via GitHub, and how are verifiers checking that they're legitimate?

Artifact releases, for example binaries. Let's assume the identity that verifiers need to verify against is specified outside the repository (otherwise, a compromise of the GitHub account would result in both the binary and which identity to verify against be changed. This does bring up another question around guidance for distributing which identities should verify which artifacts).

znewman01 commented 2 years ago

I'm wondering if this should be part of the client specification in the architecture docs - Recommended but not enforced behavior. Or maybe a section on recommended policy?

I think that could make sense for the "our deployment-specific" client documentation.

This does bring up another question around guidance for distributing which identities should verify which artifacts).

IMO that's much more important. I don't worry about "signing and deploying with the same credentials" until we have a story for "how do I even know what credentials to use to verify". And honestly I think, as a matter of policy, the GitHub signer/releaser issue should be addressed as part of that guidance, not by Sigstore infrastructure itself.