-
Notifications
You must be signed in to change notification settings - Fork 137
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
Standardizing Fulcio Certificate Extensions #945
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,52 +2,91 @@ | |
|
||
## Description | ||
|
||
Sigstore maintains its own Private Enterprise Number (57264) with the Internet | ||
Sigstore maintains its own Private Enterprise Number ([57264](http://oid-info.com/get/1.3.6.1.4.1.57264)) with the Internet | ||
Assigned Numbers Authority to help identify and organize additional metadata in | ||
code signing certificates issued by Fulcio instances. This document aims to | ||
provide a simple directory of values in use with an explanation of their | ||
meaning. | ||
|
||
## Requirements to support signing with CI/CD workload identities | ||
|
||
In order to support Sigstore code signing with CI/CD based workfload identities the following claims must be included in the OIDC ID Token. See example claim values for each extension in the detailed [Directory](#directory). | ||
|
||
Providers MAY choose to emit extension value in other formats to generic examples, and consumers MUST NOT assume the generic example format. | ||
|
||
Requirements: | ||
|
||
- MUST include `iss` claim for `Issuer` extension. | ||
- MUST include claim to support: `Build Signer URI` that identifies the specific build instructions that are responsible for signing. | ||
- MUST include claim to support: `Build Signer Digest` which is an immutable reference to a specific version of the build instructions that are responsible for signing. | ||
- MUST include claim to support: `Runner Environment` that differentiates between builds that took place in platform-hosted cloud infrastructure or customer-hosted infrastructure. | ||
|
||
Recommended: | ||
|
||
- SHOULD include `iss` that uniquely identifies ID tokens originating from the CI/CD system, e.g. not shared with OIDC OAuth 2.0 tokens for email/username logins. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the reason for this requirement? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like good hygiene to separate OIDC issuers so you don't just rely on the audience to separate? GitLab for example use the same issuer for email logins and workload identities at the moment but are working on separating these out. It could add some protections against very poorly configured OIDC trust relationships between CI <> Cloud where you only check the issuer. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense, although you could still run into issues if the OIDC issuers are run within the same trust domain such that if one is compromised, both could be. For example a CI issuer issuing a token for an email address, or an email-based issuer issuing a token for a CI identity (we do add some checks in fulcio to make sure a subject looks like an email when it's expected, I would hesitate to always enforce that a CI identity is not an email though) |
||
- SHOULD include claim to support: `Source Repository URI` | ||
- SHOULD include claim to support: `Source Repository Digest` | ||
- SHOULD include claim to support: `Source Repository Ref` | ||
- SHOULD include claim to support: `Source Repository Identifier` | ||
- SHOULD include claim to support: `Source Repository Owner URI` | ||
- SHOULD include claim to support: `Source Repository Owner Identifier` | ||
|
||
Nice-to-haves: | ||
|
||
- MAY include claim to support: `Build Config URI` | ||
- MAY include claim to support: `Build Config Digest` | ||
- MAY include claim to support: `Build Trigger` | ||
- MAY include claim to support: `Run Invocation URI` | ||
|
||
## Terminology | ||
|
||
- `Identifier`: Immutable resource identifier, e.g. uuid/primary key ID | ||
- `URI`: SHOULD be a fully qualified URL when available. MAY be a mutable resource identifier, e.g. `https://scm.com/example/repository` | ||
- Fully qualified URL: Complete URL with protocol. | ||
- `Digest`: Output of a cryptographic hash function, e.g. git commit SHA | ||
|
||
## Directory | ||
|
||
Note that all values begin from the root OID 1.3.6.1.4.1.57264 [registered by Sigstore][oid-link]. | ||
|
||
When adding additional OIDs under the root, please update the above link with the child OID. | ||
|
||
GitHub Workflow specific OID extensions have been deprecated in favor of provider generic extensions starting from 1.3.6.1.4.1.57264.1.8. | ||
|
||
## 1.3.6.1.4.1.57264.1 | Fulcio | ||
|
||
The `.1` is added to the root OID for sigstore for all OIDs set by Fulcio. | ||
|
||
### 1.3.6.1.4.1.57264.1.1 | Issuer | ||
|
||
This contains the `issuer` claim from the OIDC Identity Token that was | ||
This contains the `iss` claim from the OIDC Identity Token that was | ||
presented at the time the code signing certificate was requested to be created. | ||
This claim is the URI of the OIDC Identity Provider that digitally signed the | ||
identity token. | ||
identity token. For example: `https://oidc-issuer.com`. | ||
|
||
### 1.3.6.1.4.1.57264.1.2 | GitHub Workflow Trigger | ||
### 1.3.6.1.4.1.57264.1.2 | GitHub Workflow Trigger (deprecated) | ||
|
||
This contains the `event_name` claim from the GitHub OIDC Identity token that | ||
contains the name of the event that triggered the workflow run. | ||
[(docs)][github-oidc-doc] | ||
|
||
### 1.3.6.1.4.1.57264.1.3 | GitHub Workflow SHA | ||
### 1.3.6.1.4.1.57264.1.3 | GitHub Workflow SHA (deprecated) | ||
|
||
This contains the `sha` claim from the GitHub OIDC Identity token that contains | ||
the commit SHA that the workflow run was based upon. [(docs)][github-oidc-doc] | ||
|
||
### 1.3.6.1.4.1.57264.1.4 | GitHub Workflow Name | ||
### 1.3.6.1.4.1.57264.1.4 | GitHub Workflow Name (deprecated) | ||
|
||
This contains the `workflow` claim from the GitHub OIDC Identity token that | ||
contains the name of the executed workflow. [(docs)][github-oidc-doc] | ||
|
||
### 1.3.6.1.4.1.57264.1.5 | GitHub Workflow Repository | ||
### 1.3.6.1.4.1.57264.1.5 | GitHub Workflow Repository (deprecated) | ||
|
||
This contains the `repository` claim from the GitHub OIDC Identity token that | ||
contains the repository that the workflow run was based upon. | ||
[(docs)][github-oidc-doc] | ||
|
||
### 1.3.6.1.4.1.57264.1.6 | GitHub Workflow Ref | ||
### 1.3.6.1.4.1.57264.1.6 | GitHub Workflow Ref (deprecated) | ||
|
||
This contains the `ref` claim from the GitHub OIDC Identity token that contains | ||
the git ref that the workflow run was based upon. | ||
|
@@ -58,11 +97,90 @@ the git ref that the workflow run was based upon. | |
This specifies the username identity in the OtherName Subject Alternative Name, as | ||
defined by [RFC5280 4.2.1.6](https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.6). | ||
|
||
### 1.3.6.1.4.1.57264.1.8 | Build Signer URI | ||
|
||
Reference to specific build instructions that are responsible for signing. SHOULD be fully qualified. MAY be the same as Build Config URI. Build Signer URI is also included in the Subject Alternative Name. | ||
|
||
For example a reusable workflow ref in GitHub Actions or a Circle CI Orb name/version. For example: `https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.4.0`. | ||
|
||
### 1.3.6.1.4.1.57264.1.9 | Build Signer Digest | ||
|
||
Immutable reference to the specific version of the build instructions that is responsible for signing. For example: `abc123` git commit SHA. | ||
|
||
### 1.3.6.1.4.1.57264.1.10 | Runner Environment | ||
|
||
Runner Environment specifying whether the build took place in platform-hosted cloud infrastructure or customer/self-hosted infrastructure. For example: `[platform]-hosted` and `self-hosted`. | ||
|
||
### 1.3.6.1.4.1.57264.1.11 | Source Repository URI | ||
|
||
Source repository URL that the build was based on. SHOULD be fully qualified. For example: `https://example.com/owner/repository`. | ||
|
||
### 1.3.6.1.4.1.57264.1.12 | Source Repository Digest | ||
|
||
Immutable reference to a specific version of the source code that the build | ||
was based upon. For example: `abc123` git commit SHA. | ||
|
||
### 1.3.6.1.4.1.57264.1.13 | Source Repository Ref | ||
|
||
Source Repository Ref that the build run was based upon. For example: `refs/head/main` git branch or tag. | ||
|
||
### 1.3.6.1.4.1.57264.1.14 | Source Repository Identifier | ||
|
||
Immutable identifier for the source repository the workflow was based upon. MAY be empty if the Source Repository URI is immutable. For example: `1234` if using a primary key. | ||
|
||
### 1.3.6.1.4.1.57264.1.15 | Source Repository Owner URI | ||
|
||
Source repository owner URL of the owner of the source repository that the build was based | ||
on. SHOULD be fully qualified. MAY be empty if there is no Source Repository Owner. For example: `https://example.com/owner` | ||
|
||
### 1.3.6.1.4.1.57264.1.16 | Source Repository Owner Identifier | ||
|
||
Immutable identifier for the owner of the source repository that the workflow was based upon. MAY be empty if there is no Source Repository Owner or Source Repository Owner URI is immutable. For example: `5678` if using a primary key. | ||
|
||
### 1.3.6.1.4.1.57264.1.17 | Build Config URI | ||
|
||
Build Config URL to the top-level/initiating build instructions. SHOULD be fully qualified. For example: `https://example.com/owner/repository/build-config.yml`. | ||
|
||
### 1.3.6.1.4.1.57264.1.18 | Build Config Digest | ||
|
||
Immutable reference to the specific version of the top-level/initiating build | ||
instructions. For example: `abc123` git commit SHA. | ||
|
||
### 1.3.6.1.4.1.57264.1.19 | Build Trigger | ||
|
||
Event or action that initiated the build. For example: `push`. | ||
|
||
### 1.3.6.1.4.1.57264.1.20 | Run Invocation URI | ||
|
||
Run Invocation URL to uniquely identify the build execution. SHOULD be fully qualified. For example: `https://github.com/example/repository/actions/runs/1536140711/attempts/1`. | ||
|
||
## 1.3.6.1.4.1.57264.2 | Policy OID for Sigstore Timestamp Authority | ||
|
||
Not used by Fulcio. This specifies the policy OID for the [timestamp authority](https://github.com/sigstore/timestamp-authority) | ||
that Sigstore operates. | ||
|
||
<!-- References --> | ||
## Mapping OIDC token claims to Fulcio OIDs | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A proposed new claim: a version claim. I like the idea of sticking direct OIDC claims into the extension fields in the table. What I'm worried about is that the OID extensions are not versioned, and there is no way of allowing an OIDC provider to "update" the mapping (because we don't want to keep adding fields from this standardization). Having a Fulcio-integration "version" will help allow providers to update the table claims. For e.g. if GH decides to add a sha prefix to the source digest, assuming that Fulcio is not sanitizing or modifying claims into this table, then that would be breaking to policy verifiers. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, and IMO this is another good motivation for a single "composite" extension that wraps all of these claims as suggested in #981 (although that will need to happen with a breaking version, not here). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thought a bit more on this - Does a version that Fulcio maintains solve the problem of breaking policy verifiers? And furthermore, is that Fulcio's problem? GH making a change to the format of the source digest would affect a verifier if they were directly consuming the OIDC token. This seems more like a problem for the OIDC providers, that they should version their tokens and we can then also include that version value in an extension. Fulcio isn't opinionated on each claim structure (at least that's what we decided after chatting - If it was opinionated, then we would need a version that fulcio maintains) Adding a claim in a new extension should not be a breaking change, and clients should search for it and gracefully handle it not being present (verification policies can require the extension if it should be critical). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Chatting with Asra, throwing around some ideas (sorry if this is not clear, just trying to get this down to remember this):
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking more on this: I think we should not complicate client logic with versioning logic, and push back on integrators who will be making version breaking changes to their OIDC tokens. In a future world, I'd like OIDC tokens maybe to be versioned and for that to be represented in a claim, but I think Fulcio self-managing a versioning scheme would be pretty tough as an intermediate versioning layer between the OIDC provider and the client. As in: let's push back on integrators who won't satisfy stable claims for the ones they are committing to tin the mapping. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Leaving this open in case anyone has any other thoughts, but I think we're all in agreement that we won't attempt to do any versioning. |
||
|
||
| GitHub [(docs)][github-oidc-doc] | GitLab | CircleCI | Buildkite | Fulcio Certificate Extension | Why / Notes / Questions | | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For ref, current workload OIDC claims:
|
||
|--------------------|--------|----------|-----------|------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | ||
| aud | ?? | aud | aud | N/A | Only used to validate the JWT. | | ||
| iss | iss | iss | iss | Issuer | This already exists. For example: https://token.actions.githubusercontent.com | | ||
| exp | exp | exp | exp | N/A | Only used to validate the JWT. | | ||
| nbf | nbf | nbf | nbf | N/A | Only used to validate the JWT. | | ||
| iat | iat | iat | iat | N/A | Only used to validate the JWT. | | ||
| server_url + job_workflow_ref | ?? | ?? | ?? | Build Signer URI | Reference to specific build instructions that are responsible for signing. Can be the same as Build Config URI. For example a reusable workflow in GitHub Actions or a Circle CI Orbs. | | ||
| job_workflow_sha | ?? | ?? | ?? | Build Signer Digest | An immutable reference to the specific version of the build instructions that is responsible for signing. Should include the digest type followed by the digest, e.g. `sha1:abc123`. | | ||
| runner_environment | ?? | ?? | ?? | Runner Environment | For platforms to specify whether the build took place in platform-hosted cloud infrastructure or customer-hosted infrastructure. For example: `platform-hosted` and `self-hosted`. | | ||
| server_url + repository | project_path | ?? | ?? | Source Repository URI | Should include a fully qualified repository URL. | | ||
| sha | ?? | ?? | build_commit | Source Repository Digest | An immutable reference to a specific version of the source code. Should include the digest type followed by the digest, e.g. `sha1:abc123`. | | ||
| ref | ref | ?? | build_branch | Source Repository Ref | The source ref that the build run was based upon. For example: refs/head/main. | | ||
| repository_id | project_id | ?? | ?? | Source Repository Identifier | Stable identifier for the owner of the source repository. | | ||
| server_url + repository_owner | namespace_path | ?? | ?? | Source Repository Owner URI | Fully qualified URL for the owner of the source repository. | | ||
| repository_owner_id | namespace_id | ?? | ?? | Source Repository Owner Identifier | Stable identifier for the owner of the source repository. | | ||
| server_url + workflow_ref | ?? | ?? | ?? | Build Config URI | A reference to the initiating build instructions. | | ||
| workflow_sha | ?? | ?? | ?? | Build Config Digest | An immutable reference to the specific version of the top-level build instructions. Should include the digest type followed by the digest, e.g. `sha1:abc123`. | | ||
| event_name | pipeline_source | ?? | ?? | Build Trigger | The event or action that triggered the build. | | ||
| server_url + repository + "/actions/runs/" + run_id + "/attempts/" + run_attempt | ?? | ?? | ?? | Run Invocation URI | An immutable identifier that can uniquely identify the build execution | | ||
|
||
[github-oidc-doc]: https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#understanding-the-oidc-token | ||
[oid-link]: http://oid-info.com/get/1.3.6.1.4.1.57264 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How should these attributes be supported by services like Buildkite which offer dynamic pipelines, i.e. build instructions are not immutable and change over the course of an execution? I suppose we could include a reference to the initial build instructions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see, the directory examples suggest this could be a link to the source repository at a specific commit sha. That doesn't represent the whole signing environment for us, the instructions also involve the running pipeline, but it might be close enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, so ideally this would be an immutable reference to the Buildkite pipeline steps at the time the build ran.
How are Buildkite pipeline steps stored / versioned? If I update the pipeline steps after a build has run, is there a URL I can go to that references the previous version of the pipeline steps (e.g. the pipeline steps when the build ran)?