fulcio icon indicating copy to clipboard operation
fulcio copied to clipboard

Fulcio certs: Encode the CI/CD "environment" in an extension?

Open woodruffw opened this issue 1 year ago • 1 comments

Problem / value statement

The current Fulcio X.509 extensions include Runner Environment, which corresponds to a GitHub Actions infrastructure scope, e.g. github-hosted or self-hosted or similar.

However, there's another kind of "environment" in GitHub Actions (and possibly other CI/CD providers) as well: job within workflows can configure deployment environments, which have user-controlled names and can be mapped to deployment protection rules.

For example, here's an example of an environment (named pypi) used in an individual workflow job:

https://github.com/trailofbits/pypi-attestations/blob/464bd18b42b7ba207d6a77e9cca468116aa0406b/.github/workflows/release.yml#L39-L41

When a job references an environment, its OIDC claims include references to that environment. In particular, the sub claim contains the environment:$NAME clause, and there's also a separate environment claim that contains the environment name directly. Examples of this can be seen in GitHub's OIDC docs.

At the moment, it looks like Fulcio issued certificates don't reflect these user-controlled deployment environments, probably because there's no dedicated OID/extension definition for them. For example, this recent log entry has no reference to the pypi environment it came from. This is true even for the subject, since Fulcio rewrites the SAN away from the sub claim provided by the GitHub Actions OIDC credential.

It would be useful to include the deployment environment's name in the Fulcio extensions for a few reasons:

  1. A deployment environment can correspond to deployment protection rules, making it possible to confirm (by the repo owner at least) that a workflow ran with explicit user approval or other checks.
  2. Other OIDC applications, like Trusted Publishing, use the deployment environment as a binding piece of metadata for the publisher's "identity". It'd be nice if these identities could fully align with what Fulcio can provide.

Proposal

  1. Define a new OID + extension for Deployment Environment or similar (maybe there's a better name)
  2. Define Deployment Environment as corresponding to the environment claim on GitHub Actions and GitLab CI/CD (where it appears to have similar semantics)
  3. Begin emitting Fulcio certs with the new extension where appropriate

CC @haydentherapper @segiddins as interested parties 🙂

woodruffw avatar Oct 25 '24 16:10 woodruffw

TIL, I wasn't aware of this feature! This is neat, would be a nice way to enforce multi-party review for releases.

I'm supportive of adding this as an extension.

cc @kommendorkapten @feelepxyz for GitHub's perspective. Let's also loop in the other CI providers on the documentation update.

Hayden-IO avatar Oct 25 '24 22:10 Hayden-IO

Interesting scope with multi-party review for releases! We have discussed the usage of the environment before, but not decided to pursue it, the use-case have been unclear and no real demand for it (yet).

If we can document this properly, I think it may add value for more advanced users. The GitHub Actions environment feature is really good for managing releases and deployments, I'm using that for a ton of things. Getting the feature carried over to a signing certificate can definitely help in some scenarios.

For things like OIDC based trusted publishing (or internally build and deployed software), a feature like environment makes a ton of sense, as the trust model is managed completely by a "single entity", which knows about the expected values. The downside of the environment claim for the general OSS use-case is that it's not as clear how it should be used during verification (as it's just an opaque producer defined string), but providing this option does not hurt, as the producer can specify what information is expected OOB to the consumers.

kommendorkapten avatar Oct 28 '24 08:10 kommendorkapten

For things like OIDC based trusted publishing (or internally build and deployed software), a feature like environment makes a ton of sense, as the trust model is managed completely by a "single entity", which knows about the expected values. The downside of the environment claim for the general OSS use-case is that it's not as clear how it should be used during verification (as it's just an opaque producer defined string), but providing this option does not hurt, as the producer can specify what information is expected OOB to the consumers.

Yep, this aligns with what I was thinking! It's essentially just an opaque string from the verifying side, but when used in conjunction with Trusted Publishing it's the missing piece towards aligning the two "identities" completely 🙂

woodruffw avatar Oct 28 '24 13:10 woodruffw

Docs for the GitLab version of environments is here: https://docs.gitlab.com/ci/environments/, this corresponds to the environment claim there as well.

di avatar Oct 28 '25 17:10 di

Yay!

woodruffw avatar Nov 04 '25 19:11 woodruffw

We'll get this rolled out shortly!

Hayden-IO avatar Nov 04 '25 19:11 Hayden-IO

For GitHub, environment is only included when running a workflow from an environment. Fulcio currently expects that every configured claim has a value. Will need to think through how to handle claims conditionally.

I haven't tested GitLab yet, but I'll assume it's affected by the same issue.

Hayden-IO avatar Nov 12 '25 23:11 Hayden-IO