From f44933ec61571735b61bf4697ac2b818e73bad3a Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Mon, 20 May 2024 05:44:51 +0000 Subject: [PATCH 01/23] Add GitHub Artifact Attestations post Signed-off-by: Ian Lewis --- ...erstanding-github-artifact-attestations.md | 224 ++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 en/_posts/2024-05-23-understanding-github-artifact-attestations.md diff --git a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md new file mode 100644 index 0000000..3b7f27b --- /dev/null +++ b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md @@ -0,0 +1,224 @@ +--- +layout: post +title: "Understanding GitHub Artifact Attestaitons" +date: 2024-05-23 00:00:00 +0000 +permalink: /en/understanding-github-artifact-attestations +blog: en +tags: security slsa +render_with_liquid: false +--- + +GitHub recently released [GitHub Actions Artifact +Attestations](https://github.blog/2024-05-02-introducing-artifact-attestations-now-in-public-beta/) +in beta. + +Artifact Attestations are a great step forward in improving the supply chain +security of Open Source software. It links an artifact to its source code +repository and to GitHub Actions. This means that we can be sure that it wasn’t +built with some unknown, potentially malicious source code or on a random +person’s laptop. + +GitHub did a great job explaining how it works in their blog post. They also +have some more comprehensive +[documentation](https://docs.github.com/en/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds#about-slsa-levels-for-artifact-attestations) +on artifact attestations. However, there are a few questions one might ask and +aren't covered. What does verification do and why is it secure? Why does it say +that artifact attestations achieve [SLSA v1.0 Build Level 2 and not +L3](https://docs.github.com/en/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds#about-slsa-levels-for-artifact-attestations)? +How could you achieve L3 with artifact attestations? + +I’ll do my best to answer some of these questions here. But first we need to +understand a bit about how GitHub Artifact Attestations work and their relation +to SLSA levels. + +## Architecture + +Generating attestations is done using the +[`attest-build-provenance`](https://github.com/actions/attest-build-provenance) +GitHub action. Github’s blog post does a good job of explaining how it works so +I won’t rehash it fully here. I’ll just summarize the flow and highlight some +additional information that will be important later. + +1. `attest-build-provenance` requests an OIDC token from the GitHub OIDC + provider. This OIDC token contains [information about the + build](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#understanding-the-oidc-token) + in the token claims. + +2. The OIDC token is sent to a [Sigstore + Fulcio](https://github.com/sigstore/fulcio) server (either the public instance + or GitHub’s private one). [Fulcio can recognize and validate GitHub’s OIDC + tokens](https://docs.sigstore.dev/certificate_authority/oidc-in-fulcio/#github) + and, after verifying its signature, issues a certificate in exchange for the + OIDC token. This certificate includes much of the information from the OIDC + token [mapped into its OID extension + fields](https://github.com/sigstore/fulcio/blob/main/docs/oid-info.md#mapping-oidc-token-claims-to-fulcio-oids) + as claims. + +3. SLSA Provenance is generated and the resulting JSON is signed with the + returned certificate’s private key. This private key is then discarded. + The provenance is recorded in GitHub’s attestation store. + +I'm leaving out some details but this is the general flow for attestation. So +as a result we have some provenance in JSON format and a Sigstore certificate +with some OID claims set. + +After we have an artifact and attestation, as a user, we need to be able to +verify it before we use it. Verification works something like the following. +The code for this is found in the [`gh attestations verify +command`](https://github.com/cli/cli/tree/trunk/pkg/cmd/attestation/verify) +for GitHub’s official CLI tool. + +1. The attestation is downloaded from the GitHub Attestations API using the + artifact’s digest. +2. The attestation’s signature is verified against the public key used to sign + it, and to the certificate chain for either the GitHub Fulcio instance, or + the public Sigstore Fulcio instance (the root certificates are managed using + [TUF](https://theupdateframework.io/)). +3. The expected values for the owner or repo given by the user are matched + against the signing certificate’s OID claims. + +Notice that nowhere here did we actually use the contents of the SLSA +provenance for verification. We’ll discuss why this is below. + +## A Good User Experience + +By providing a GitHub Action, GitHub gives users the maximum amount of +flexibility when integrating this into their GitHub Actions workflows. It’s +really easy to add a job step to your workflow and pass it a path to your +artifact file. + +``` +- name: Attest Build Provenance + uses: actions/attest-build-provenance@897ed5eab6ed058a474202017ada7f40bfa52940 # v1.0.0 + with: + subject-path: "bin/my-artifact.tar.gz" +``` + +Easy-to-use UX is really important for security because it increases adoption. +This can’t be understated and is an often overlooked aspect of security +software. + +## Why SLSA Build L2? + +But if this is a fairly secure solution, why is this SLSA Build L2 and not L3? +The main reason is that, by itself, the `attest-build-provenance` action +doesn’t meet this requirement for [SLSA Build +L3](https://slsa.dev/spec/v1.0/levels#build-l3-hardened-builds): + +prevent secret material used to sign the provenance from being accessible to the user-defined build steps. + +Because GitHub Actions are run in the same job VM with other build steps there +is a chance that the user-defined build steps could access the secret material, +namely the certificate’s private key provided by Fulcio, and use it for +nefarious purposes. Normally an attacker, by compromising the build, might be +able to use this key material to make up their own provenance for a malicious +artifact and sign it with the key. + +However, as we’ll see, this kind of attack is mostly mitigated by using Sigstore. + +## SLSA Build L2+? + +By using Sigstore’s Fulcio the certificate used to sign the provenance contains +much of the provenance information in its OID claims. These claims are signed +by part of Fulcio instance’s certificate chain and thus cannot be modified by +the user-defined build steps unless the Sigstore instance or GitHub’s OIDC +provider are compromised. + +So while the SLSA provenance itself might be modified the certificate OID +claims cannot. So GitHub can check the OID claims against the expected values +in order to verify them even though the user-defined build steps had access to +the signing key. So this is why verification doesn’t rely on the provenance +itself and instead relies on the certificate’s OID claims for verification. + +Some folks have colloquially referred to this combination of Sigstore and SLSA +Build L2 as SLSA Build L2+ since it provides some of the benefits of SLSA Build +L3 without actually fulfilling all of the requirements of L3. + +## Limits of SLSA Build L2+ + +However, this comes with a caveat. This means that if the user-defined build +steps could have access to the signing keys then **only** the information in +the certificate’s OID claims are trustworthy. No information that isn’t +included in these claims can be included in the provenance because it can’t be +verified later. + +Crucially this includes values like the GitHub Actions workflow +[`inputs`](https://docs.github.com/en/actions/learn-github-actions/contexts#inputs-context) +and +[`vars`](https://docs.github.com/en/actions/learn-github-actions/contexts#vars-context) +contexts. These include the inputs into a build and could potentially be used +for script injection attacks. While they can’t be used to attack the provenance +itself, they could be used to attack the build without leaving any trace in the +provenance. + +This means that while GitHub Artifact Attestations can be used with policy +engines/tools like Rego, Cue, and OPA, these policies can’t be evaluated on the +build inputs. For example, to verify that the build had no inputs etc. in order +to prevent these kinds of attacks. + +This architecture also relies heavily on Sigstore’s Fulcio Certificate +Authority to map the OID claims. This means that it’s hard to use separate +private PKI, such as static keys, to sign and verify provenance. While this +isn’t likely a problem for Open Source projects, some enterprises have these +kinds of requirements. + +## Achieving SLSA Build L3 with GitHub Artifact Attestations + +In the documentation [SLSA Build L3 is described as +achievable](https://github.blog/2024-05-02-introducing-artifact-attestations-now-in-public-beta/#an-effortless-user-experience) +but it focuses on SLSA Build L2(+) and L3 is left as an exercise for the +reader. So what would it take to achieve SLSA Build L3 with GitHub Artifact +Attestations? + +The solution is fairly somewhat so I will just summarize the requirements here +and leave the details for a later blog post. In order to achieve L3 you, at a +minimum, would roughly need to do the following things: + +- The artifact build would need to be done in a separate job from the call to + `attest-build-provenance`. This ensures that the build and provenance signing + happen on [separate virtual + machines](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions#the-components-of-github-actions) + and that the artifact build steps will not have access to the signing + material. This job should **not** have `attestations: write` permissions. +- The `attest-build-provenance` action is passed a path to the artifact. Jobs + execute on separate VMs so the artifact itself would need to be passed from + the build job to the attestation job. This will need to be done by uploading + the artifact file as a [workflow + artifact](https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts) + from the first job and downloading it in the second job. However, this + artifact could be overwritten by concurrently running build steps. So you + will need to take a checksum (sha256 etc.) and pass it from the build job to + the provenance signing job using job inputs/outputs, and verify it after + download. + +## Conclusion + +Trust in GitHub’s Artifact Attestations trust really lies in the Sigstore +certificate and its OID claims. The signed SLSA provenance is really only nice +to have. GitHub ensures that the JSON printed by the `gh` client’s `--format +json` option is trustworthy simply by omitting any values from the SLSA +provenance JSON that are not included in the certificate’s OID claims. This +means that the certificate itself effectively functions as the provenance. This +is fine, SLSA doesn’t even mandate that provenance be in SLSA format, but it’s +an important point to understand. + +As an aside, it’s interesting to note that GitHub’s [npm package +provenance](https://github.blog/2023-04-19-introducing-npm-package-provenance/), +which was announced last year, shares many of the same architectural benefits +and shortcomings we’ve discussed here. + +In the future I’d like to see more CI/CD systems that are more conducive to +verifiable software supply chains. + +1. Well defined build inputs and outputs. +2. Builds that are isolated from each other. More build primitives for isolation. +3. Provenance generation that is decoupled from signing +4. More options for verifiable reproducibility. +5. Multi-tenant transparency logs for organizations and private repos + +Maybe one day. + +In the meantime, GitHub’s Artifact attestations are a really exciting new +feature on GitHub and a great step in the right direction. I would strongly +consider integrating it into your workflows, and artifact verification into your +deployments. From c0ad5f7d8770ee06c7dba0f8c037a36e73299650 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Mon, 20 May 2024 06:32:13 +0000 Subject: [PATCH 02/23] spelling Signed-off-by: Ian Lewis --- .../2024-05-23-understanding-github-artifact-attestations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md index 3b7f27b..2c17d3d 100644 --- a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md @@ -1,6 +1,6 @@ --- layout: post -title: "Understanding GitHub Artifact Attestaitons" +title: "Understanding GitHub Artifact Attestations" date: 2024-05-23 00:00:00 +0000 permalink: /en/understanding-github-artifact-attestations blog: en From f861586d62f4b0258323f221fe20feec294718a9 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Wed, 22 May 2024 08:47:13 +0000 Subject: [PATCH 03/23] Fix typo Signed-off-by: Ian Lewis --- .../2024-05-23-understanding-github-artifact-attestations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md index 2c17d3d..0be9111 100644 --- a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md @@ -170,7 +170,7 @@ but it focuses on SLSA Build L2(+) and L3 is left as an exercise for the reader. So what would it take to achieve SLSA Build L3 with GitHub Artifact Attestations? -The solution is fairly somewhat so I will just summarize the requirements here +The solution is somewhat complex so I will just summarize the requirements here and leave the details for a later blog post. In order to achieve L3 you, at a minimum, would roughly need to do the following things: From 730e38047cda9d3a4f8b4e73e8065820b9cbaee7 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Wed, 22 May 2024 09:09:29 +0000 Subject: [PATCH 04/23] Reword Signed-off-by: Ian Lewis --- ...05-23-understanding-github-artifact-attestations.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md index 0be9111..3dc6700 100644 --- a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md @@ -196,11 +196,11 @@ minimum, would roughly need to do the following things: Trust in GitHub’s Artifact Attestations trust really lies in the Sigstore certificate and its OID claims. The signed SLSA provenance is really only nice to have. GitHub ensures that the JSON printed by the `gh` client’s `--format -json` option is trustworthy simply by omitting any values from the SLSA -provenance JSON that are not included in the certificate’s OID claims. This -means that the certificate itself effectively functions as the provenance. This -is fine, SLSA doesn’t even mandate that provenance be in SLSA format, but it’s -an important point to understand. +json` option is trustworthy simply by forbidding values in the SLSA provenance +JSON that are different from the certificate’s OID claims. This means that the +certificate itself effectively functions as the provenance. This is fine, SLSA +doesn’t even mandate that provenance be in SLSA format, but it’s an important +point to understand. As an aside, it’s interesting to note that GitHub’s [npm package provenance](https://github.blog/2023-04-19-introducing-npm-package-provenance/), From 3d08a1af323c78c238555dec4c21d10d632bfaa4 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Wed, 22 May 2024 09:19:40 +0000 Subject: [PATCH 05/23] Update use of provenance/predicate Signed-off-by: Ian Lewis --- ...erstanding-github-artifact-attestations.md | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md index 3dc6700..61ac733 100644 --- a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md @@ -43,24 +43,26 @@ additional information that will be important later. provider. This OIDC token contains [information about the build](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#understanding-the-oidc-token) in the token claims. - 2. The OIDC token is sent to a [Sigstore - Fulcio](https://github.com/sigstore/fulcio) server (either the public instance - or GitHub’s private one). [Fulcio can recognize and validate GitHub’s OIDC + Fulcio](https://github.com/sigstore/fulcio) server (either the public + instance or GitHub’s private one). [Fulcio can recognize and validate GitHub’s + OIDC tokens](https://docs.sigstore.dev/certificate_authority/oidc-in-fulcio/#github) and, after verifying its signature, issues a certificate in exchange for the OIDC token. This certificate includes much of the information from the OIDC token [mapped into its OID extension fields](https://github.com/sigstore/fulcio/blob/main/docs/oid-info.md#mapping-oidc-token-claims-to-fulcio-oids) as claims. - -3. SLSA Provenance is generated and the resulting JSON is signed with the - returned certificate’s private key. This private key is then discarded. - The provenance is recorded in GitHub’s attestation store. +3. A SLSA attestation + [predicate](https://github.com/in-toto/attestation/blob/main/spec/v1/predicate.md) + is generated and the provenance statement is signed with the returned + certificate’s private key. The resulting signature is combined with the + provenance to create a full attestation bundle and this bundle is recorded in + GitHub’s attestation store. I'm leaving out some details but this is the general flow for attestation. So -as a result we have some provenance in JSON format and a Sigstore certificate -with some OID claims set. +as a result we have an attestation bundle in JSON format and a Sigstore +certificate with some OID claims set. After we have an artifact and attestation, as a user, we need to be able to verify it before we use it. Verification works something like the following. @@ -78,7 +80,7 @@ for GitHub’s official CLI tool. against the signing certificate’s OID claims. Notice that nowhere here did we actually use the contents of the SLSA -provenance for verification. We’ll discuss why this is below. +predicate for verification. We’ll discuss why this is below. ## A Good User Experience @@ -118,17 +120,17 @@ However, as we’ll see, this kind of attack is mostly mitigated by using Sigsto ## SLSA Build L2+? -By using Sigstore’s Fulcio the certificate used to sign the provenance contains -much of the provenance information in its OID claims. These claims are signed -by part of Fulcio instance’s certificate chain and thus cannot be modified by -the user-defined build steps unless the Sigstore instance or GitHub’s OIDC -provider are compromised. +By using Sigstore’s Fulcio, the certificate used to sign the provenance +contains much of the SLSA predicate's information in its OID claims. These +claims are signed by part of Fulcio instance’s certificate chain and thus +cannot be modified by the user-defined build steps unless the Sigstore instance +or GitHub’s OIDC provider are compromised. -So while the SLSA provenance itself might be modified the certificate OID +So while the SLSA predicate itself might be modified the certificate OID claims cannot. So GitHub can check the OID claims against the expected values in order to verify them even though the user-defined build steps had access to -the signing key. So this is why verification doesn’t rely on the provenance -itself and instead relies on the certificate’s OID claims for verification. +the signing key. So this is why verification doesn’t rely on the predicate +and instead relies on the certificate’s OID claims for verification. Some folks have colloquially referred to this combination of Sigstore and SLSA Build L2 as SLSA Build L2+ since it provides some of the benefits of SLSA Build @@ -139,8 +141,8 @@ L3 without actually fulfilling all of the requirements of L3. However, this comes with a caveat. This means that if the user-defined build steps could have access to the signing keys then **only** the information in the certificate’s OID claims are trustworthy. No information that isn’t -included in these claims can be included in the provenance because it can’t be -verified later. +included in these claims can be included in the SLSA predicate because it can’t +be verified later. Crucially this includes values like the GitHub Actions workflow [`inputs`](https://docs.github.com/en/actions/learn-github-actions/contexts#inputs-context) From cbad72591c34d86714dcaa1893936b83a7b5ec3d Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Thu, 23 May 2024 13:43:03 +0000 Subject: [PATCH 06/23] add some examples Signed-off-by: Ian Lewis --- ...erstanding-github-artifact-attestations.md | 113 +++++++++++++++++- 1 file changed, 109 insertions(+), 4 deletions(-) diff --git a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md index 61ac733..ae6c156 100644 --- a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md @@ -27,9 +27,10 @@ that artifact attestations achieve [SLSA v1.0 Build Level 2 and not L3](https://docs.github.com/en/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds#about-slsa-levels-for-artifact-attestations)? How could you achieve L3 with artifact attestations? -I’ll do my best to answer some of these questions here. But first we need to -understand a bit about how GitHub Artifact Attestations work and their relation -to SLSA levels. +I’ll do my best to answer some of these questions here, detail why I think +there's still room for improvement, and how we could build more secure +solutions for users of GitHub Actions. But first we need to understand a bit +about how GitHub Artifact Attestations work and their relation to SLSA levels. ## Architecture @@ -43,6 +44,31 @@ additional information that will be important later. provider. This OIDC token contains [information about the build](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#understanding-the-oidc-token) in the token claims. + + Here's what a typical OIDC token's fields look like: + + ```json + { + "aud": "https://github.com/octo-org", + "iss": "https://token.actions.githubusercontent.com", + "job_workflow_ref": "octo-org/octo-automation/.github/workflows/oidc.yml@refs/heads/main", + "runner_environment": "github-hosted" + "repository": "octo-org/octo-repo", + "sha": "example-sha", + "ref": "refs/heads/main", + "repository_id": "74", + "repository_owner": "octo-org", + "repository_owner_id": "65", + "workflow": "example-workflow", + "event_name": "workflow_dispatch", + "run_id": "example-run-id", + "run_number": "10", + "run_attempt": "2", + "repository_visibility": "private", + // ... + } + ``` + 2. The OIDC token is sent to a [Sigstore Fulcio](https://github.com/sigstore/fulcio) server (either the public instance or GitHub’s private one). [Fulcio can recognize and validate GitHub’s @@ -52,7 +78,46 @@ additional information that will be important later. OIDC token. This certificate includes much of the information from the OIDC token [mapped into its OID extension fields](https://github.com/sigstore/fulcio/blob/main/docs/oid-info.md#mapping-oidc-token-claims-to-fulcio-oids) - as claims. + as OID claims. + + ```shell + $ openssl x509 -in certificate.crt -text -noout + ... + X509v3 extensions: [37/636] + X509v3 Key Usage: critical + Digital Signature + X509v3 Extended Key Usage: + Code Signing + X509v3 Subject Key Identifier: + 40:16:4D:A9:02:0E:97:E7:40:BA:A1:72:87:1A:1B:D0:FF:A4:30:FF + X509v3 Authority Key Identifier: + DF:D3:E9:CF:56:24:11:96:F9:A8:D8:E9:28:55:A2:C6:2E:18:64:3F + X509v3 Subject Alternative Name: critical + URI:https://github.com/ianlewis/gha-artifact-attestations-test/.github/workflows/artifact-attestations.basic.yml@refs/heads/main + 1.3.6.1.4.1.57264.1.1: + https://token.actions.githubusercontent.com + 1.3.6.1.4.1.57264.1.2: + push + 1.3.6.1.4.1.57264.1.3: + 9e68bb76632788dc01c6596298fb015f46b7fe0f + 1.3.6.1.4.1.57264.1.4: + Test Artifact Attestations + 1.3.6.1.4.1.57264.1.5: + ianlewis/gha-artifact-attestations-test + 1.3.6.1.4.1.57264.1.6: + refs/heads/main + 1.3.6.1.4.1.57264.1.8: + .+https://token.actions.githubusercontent.com + 1.3.6.1.4.1.57264.1.9: + .|https://github.com/ianlewis/gha-artifact-attestations-test/.github/workflows/artifact-attestations.basic.yml@refs/heads/main + 1.3.6.1.4.1.57264.1.10: + .(9e68bb76632788dc01c6596298fb015f46b7fe0f + 1.3.6.1.4.1.57264.1.11: + github-hosted . + 1.3.6.1.4.1.57264.1.12: + .:https://github.com/ianlewis/gha-artifact-attestations-test + ``` + 3. A SLSA attestation [predicate](https://github.com/in-toto/attestation/blob/main/spec/v1/predicate.md) is generated and the provenance statement is signed with the returned @@ -60,6 +125,46 @@ additional information that will be important later. provenance to create a full attestation bundle and this bundle is recorded in GitHub’s attestation store. + The SLSA predicate looks something like this: + + ```json + { + "buildDefinition": { + "buildType": "https://slsa-framework.github.io/github-actions-buildtypes/workflow/v1", + "externalParameters": { + "workflow": { + "ref": "refs/heads/main", + "repository": "https://github.com/ianlewis/gha-artifact-attestations-test", + "path": ".github/workflows/artifact-attestations.basic.yml" + } + }, + "internalParameters": { + "github": { + "event_name": "push", + "repository_id": "803607921", + "repository_owner_id": "49289" + } + }, + "resolvedDependencies": [ + { + "uri": "git+https://github.com/ianlewis/gha-artifact-attestations-test@refs/heads/main", + "digest": { + "gitCommit": "9e68bb76632788dc01c6596298fb015f46b7fe0f" + } + } + ] + }, + "runDetails": { + "builder": { + "id": "https://github.com/actions/runner/github-hosted" + }, + "metadata": { + "invocationId": "https://github.com/ianlewis/gha-artifact-attestations-test/actions/runs/9171197474/attempts/1" + } + } + } + ``` + I'm leaving out some details but this is the general flow for attestation. So as a result we have an attestation bundle in JSON format and a Sigstore certificate with some OID claims set. From 1ed73579c27448d4df7f4396f292d790a6af741f Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Thu, 23 May 2024 13:48:25 +0000 Subject: [PATCH 07/23] Add emphasis Signed-off-by: Ian Lewis --- .../2024-05-23-understanding-github-artifact-attestations.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md index ae6c156..dfdf4d3 100644 --- a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md @@ -166,8 +166,8 @@ additional information that will be important later. ``` I'm leaving out some details but this is the general flow for attestation. So -as a result we have an attestation bundle in JSON format and a Sigstore -certificate with some OID claims set. +as a result we have both an attestation bundle in JSON format **and** a +Sigstore certificate with some OID claims set. After we have an artifact and attestation, as a user, we need to be able to verify it before we use it. Verification works something like the following. From bbc8e6cbb99c96b07ae04e3f037add2dfe6eabe0 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Thu, 23 May 2024 14:25:04 +0000 Subject: [PATCH 08/23] Update Signed-off-by: Ian Lewis --- ...erstanding-github-artifact-attestations.md | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md index dfdf4d3..2cf7309 100644 --- a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md @@ -37,8 +37,8 @@ about how GitHub Artifact Attestations work and their relation to SLSA levels. Generating attestations is done using the [`attest-build-provenance`](https://github.com/actions/attest-build-provenance) GitHub action. Github’s blog post does a good job of explaining how it works so -I won’t rehash it fully here. I’ll just summarize the flow and highlight some -additional information that will be important later. +I won’t rehash it fully here. Instead, I’ll summarize the flow and highlight +some additional information that will be important later. 1. `attest-build-provenance` requests an OIDC token from the GitHub OIDC provider. This OIDC token contains [information about the @@ -184,15 +184,19 @@ for GitHub’s official CLI tool. 3. The expected values for the owner or repo given by the user are matched against the signing certificate’s OID claims. -Notice that nowhere here did we actually use the contents of the SLSA -predicate for verification. We’ll discuss why this is below. +Notice that nowhere here did we actually use the contents of the SLSA predicate +for verification. I think this is an oversight but we’ll discuss why that might +have been omitted below. + +Next, let's discuss some of the trade-offs of this architecture. + + ## A Good User Experience -By providing a GitHub Action, GitHub gives users the maximum amount of -flexibility when integrating this into their GitHub Actions workflows. It’s -really easy to add a job step to your workflow and pass it a path to your -artifact file. +By providing a GitHub Action, GitHub gives users flexibility when integrating +this into their GitHub Actions workflows. It’s simple to add a job step to +your workflow and pass it a path to your artifact file. ``` - name: Attest Build Provenance From 7fec3c7501f88f3c40455c53fd9ea9113dffc8e6 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Mon, 27 May 2024 11:33:18 +0000 Subject: [PATCH 09/23] Edits Signed-off-by: Ian Lewis --- .../sigstore.excalidraw | 672 ++++++++++++++++++ .../sigstore.png | Bin 0 -> 109860 bytes ...erstanding-github-artifact-attestations.md | 268 ++++--- 3 files changed, 794 insertions(+), 146 deletions(-) create mode 100644 assets/images/2024-05-23-understanding-github-artifact-attestations/sigstore.excalidraw create mode 100644 assets/images/2024-05-23-understanding-github-artifact-attestations/sigstore.png diff --git a/assets/images/2024-05-23-understanding-github-artifact-attestations/sigstore.excalidraw b/assets/images/2024-05-23-understanding-github-artifact-attestations/sigstore.excalidraw new file mode 100644 index 0000000..7ef0586 --- /dev/null +++ b/assets/images/2024-05-23-understanding-github-artifact-attestations/sigstore.excalidraw @@ -0,0 +1,672 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "rectangle", + "version": 439, + "versionNonce": 1183051029, + "index": "a0", + "isDeleted": false, + "id": "4Tti92--0H7gjpAUScH3G", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 342.17364501953125, + "y": 286.07106018066406, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 296.2780151367187, + "height": 71.73760986328125, + "seed": 286998613, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "vYBURjhpnidE-WDIsIZDb" + }, + { + "id": "aTbcjlKf330UEpgFWTOzf", + "type": "arrow" + }, + { + "id": "v8DBp9AgXxaiFDDDZEYSp", + "type": "arrow" + }, + { + "id": "9cECIUVZDwqies7kKZQT5", + "type": "arrow" + }, + { + "id": "JaMoxQRsdp7k7NFEJb32C", + "type": "arrow" + } + ], + "updated": 1716807618801, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 285, + "versionNonce": 1802150302, + "index": "a1", + "isDeleted": false, + "id": "vYBURjhpnidE-WDIsIZDb", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 374.3327865600586, + "y": 309.4398651123047, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 231.95973205566406, + "height": 25, + "seed": 1024425179, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716808927627, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "attest-build-provenance", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "4Tti92--0H7gjpAUScH3G", + "originalText": "attest-build-provenance", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 218, + "versionNonce": 1763496539, + "index": "a2", + "isDeleted": false, + "id": "0yxlK86e283LeVjHXFVRS", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 336.0631103515625, + "y": 105.1209716796875, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 304.36248779296875, + "height": 51.36630249023438, + "seed": 1762557781, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "rUeGhcyqfkHSNZvEEli-S" + }, + { + "id": "aTbcjlKf330UEpgFWTOzf", + "type": "arrow" + } + ], + "updated": 1716808230290, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 186, + "versionNonce": 1329614658, + "index": "a3", + "isDeleted": false, + "id": "rUeGhcyqfkHSNZvEEli-S", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 424.29441833496094, + "y": 118.30412292480469, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 127.89987182617188, + "height": 25, + "seed": 215913147, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716808927627, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "GitHub OIDC", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "0yxlK86e283LeVjHXFVRS", + "originalText": "GitHub OIDC", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 299, + "versionNonce": 1648194523, + "index": "a4", + "isDeleted": false, + "id": "DfzDvf0kupVnu5v3j4-dJ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1012.3241882324219, + "y": 275.79872131347656, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 143.46673583984375, + "height": 60.37509155273437, + "seed": 1342436219, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "type": "text", + "id": "B6kV5n9xaGtiYWzrbFDYT" + }, + { + "id": "v8DBp9AgXxaiFDDDZEYSp", + "type": "arrow" + }, + { + "id": "9cECIUVZDwqies7kKZQT5", + "type": "arrow" + } + ], + "updated": 1716808336741, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 281, + "versionNonce": 2132852190, + "index": "a5", + "isDeleted": false, + "id": "B6kV5n9xaGtiYWzrbFDYT", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1057.257583618164, + "y": 293.48626708984375, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 53.599945068359375, + "height": 25, + "seed": 1808649243, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716808927627, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Fulcio", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "DfzDvf0kupVnu5v3j4-dJ", + "originalText": "Fulcio", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 669, + "versionNonce": 219423541, + "index": "a7", + "isDeleted": false, + "id": "aTbcjlKf330UEpgFWTOzf", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 364.69518081008573, + "y": 159.5433349609375, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 2.9754205556057514, + "height": 120.10044860839844, + "seed": 216623963, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1716808234285, + "link": null, + "locked": false, + "startBinding": { + "elementId": "0yxlK86e283LeVjHXFVRS", + "focus": 0.8038160034155345, + "gap": 3.056060791015625 + }, + "endBinding": { + "elementId": "4Tti92--0H7gjpAUScH3G", + "focus": -0.869910819869183, + "gap": 6.427276611328125 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -2.9754205556057514, + 120.10044860839844 + ] + ] + }, + { + "type": "arrow", + "version": 397, + "versionNonce": 1944385365, + "index": "a9", + "isDeleted": false, + "id": "v8DBp9AgXxaiFDDDZEYSp", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 638.822265625, + "y": 280.80894470214844, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 372.73468017578125, + "height": 57.728271484375, + "seed": 721866933, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1716808341319, + "link": null, + "locked": false, + "startBinding": { + "elementId": "4Tti92--0H7gjpAUScH3G", + "focus": 0.06478487244907707, + "gap": 5.262115478515625 + }, + "endBinding": { + "elementId": "DfzDvf0kupVnu5v3j4-dJ", + "focus": 0.43871401398986964, + "gap": 7.846358297481288 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 184.5411376953125, + -57.728271484375 + ], + [ + 372.73468017578125, + -12.856581686153163 + ] + ] + }, + { + "type": "arrow", + "version": 366, + "versionNonce": 483958203, + "index": "aA", + "isDeleted": false, + "id": "9cECIUVZDwqies7kKZQT5", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1029.2630772047282, + "y": 349.2771627591415, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 390.867752497697, + "height": 41.44968965785068, + "seed": 1154908885, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1716808336741, + "link": null, + "locked": false, + "startBinding": { + "elementId": "DfzDvf0kupVnu5v3j4-dJ", + "focus": -0.6953780624930885, + "gap": 13.103349892930567 + }, + "endBinding": { + "elementId": "4Tti92--0H7gjpAUScH3G", + "focus": 0.28067077697491943, + "gap": 3.053680419921875 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -194.57252544691573, + 41.44968965785068 + ], + [ + -390.867752497697, + 11.585187704725683 + ] + ] + }, + { + "type": "text", + "version": 350, + "versionNonce": 247011074, + "index": "aB", + "isDeleted": false, + "id": "d8zVG_lUN7ppSKEnjkQva", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 659.6842041015625, + "y": 281.55731201171875, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 338.09967041015625, + "height": 50, + "seed": 74649499, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "v8DBp9AgXxaiFDDDZEYSp", + "type": "arrow" + }, + { + "id": "9cECIUVZDwqies7kKZQT5", + "type": "arrow" + } + ], + "updated": 1716808927628, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "2. Exchange OIDC token for cert\n1.3.6.1.4.1.57264.1.5: ianlewis/myrepo", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "2. Exchange OIDC token for cert\n1.3.6.1.4.1.57264.1.5: ianlewis/myrepo", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 1169, + "versionNonce": 1423936725, + "index": "aD", + "isDeleted": false, + "id": "JaMoxQRsdp7k7NFEJb32C", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 468.7886747620609, + "y": 362.2537078857422, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 65.84621367910228, + "height": 112.4518975932437, + "seed": 2053577813, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1716808398239, + "link": null, + "locked": false, + "startBinding": { + "elementId": "4Tti92--0H7gjpAUScH3G", + "gap": 4.445037841796875, + "focus": 0.26616533660553987 + }, + "endBinding": { + "elementId": "-UBP1XbU24_6HLIZz9DI-", + "gap": 10.0413818359375, + "focus": -0.5528664715956453 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 65.84621367910228, + 112.4518975932437 + ] + ] + }, + { + "type": "rectangle", + "version": 662, + "versionNonce": 282307765, + "index": "aE", + "isDeleted": false, + "id": "-UBP1XbU24_6HLIZz9DI-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 541.6451416015625, + "y": 481.89488220214844, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 414.524658203125, + "height": 210, + "seed": 149404923, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "JaMoxQRsdp7k7NFEJb32C", + "type": "arrow" + }, + { + "type": "text", + "id": "75jpBpq96NoePeKzaTuxU" + } + ], + "updated": 1716808398238, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 650, + "versionNonce": 642339358, + "index": "aEV", + "isDeleted": false, + "id": "75jpBpq96NoePeKzaTuxU", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 579.8576354980469, + "y": 486.89488220214844, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 338.09967041015625, + "height": 200, + "seed": 333134555, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716808927628, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Provenance Predicate\n{\"repository\": \"ianlewis/myrepo\"}\n\nProvenance Signature\n\"sig\": \"MEUCIAgh6r2tXsy2eKzC9\"\n\nSigning Certificate (-private key)\n1.3.6.1.4.1.57264.1.5: ianlewis/myrepo", + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "-UBP1XbU24_6HLIZz9DI-", + "originalText": "Provenance Predicate\n{\"repository\": \"ianlewis/myrepo\"}\n\nProvenance Signature\n\"sig\": \"MEUCIAgh6r2tXsy2eKzC9\"\n\nSigning Certificate (-private key)\n1.3.6.1.4.1.57264.1.5: ianlewis/myrepo", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 328, + "versionNonce": 994240194, + "index": "aJ", + "isDeleted": false, + "id": "xSz3qJzciydTDWgMyyWTk", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 372.94181060791016, + "y": 188.7642059326172, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 254.11968994140625, + "height": 50, + "seed": 1432804475, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716808927628, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "1. Get OIDC Token\nrepository: ianlewis/myrepo", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "1. Get OIDC Token\nrepository: ianlewis/myrepo", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 249, + "versionNonce": 1003839070, + "index": "aL", + "isDeleted": false, + "id": "2S39J5jXoPh8BgAJnnBMO", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 595.114501953125, + "y": 446.00880432128906, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 301.0596923828125, + "height": 25, + "seed": 2093164027, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1716808927628, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "3. Generate Provenace Bundle", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "3. Generate Provenace Bundle", + "autoResize": true, + "lineHeight": 1.25 + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/assets/images/2024-05-23-understanding-github-artifact-attestations/sigstore.png b/assets/images/2024-05-23-understanding-github-artifact-attestations/sigstore.png new file mode 100644 index 0000000000000000000000000000000000000000..56b31c18257c404000bc609f8bc1cd50df35da15 GIT binary patch literal 109860 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

gR7kba)((0vRC!a1{u4kRv%@@ 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 JeMOoC{9j?I(O>`o literal 0 HcmV?d00001 diff --git a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md index 2cf7309..2d8d6ac 100644 --- a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md @@ -8,31 +8,28 @@ tags: security slsa render_with_liquid: false --- -GitHub recently released [GitHub Actions Artifact -Attestations](https://github.blog/2024-05-02-introducing-artifact-attestations-now-in-public-beta/) -in beta. - -Artifact Attestations are a great step forward in improving the supply chain -security of Open Source software. It links an artifact to its source code -repository and to GitHub Actions. This means that we can be sure that it wasn’t -built with some unknown, potentially malicious source code or on a random -person’s laptop. - -GitHub did a great job explaining how it works in their blog post. They also -have some more comprehensive +GitHub recently introduced [Artifact +Attestations](https://github.blog/2024-05-02-introducing-artifact-attestations-now-in-public-beta/), +a beta feature that enhances the security of Open Source software supply +chains. By linking artifacts to their source code repositories and GitHub +Actions, it ensures that artifacts are not built with malicious or unknown code +or on potentially compromised devices. + +GitHub's blog post and [documentation](https://docs.github.com/en/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds#about-slsa-levels-for-artifact-attestations) -on artifact attestations. However, there are a few questions one might ask and -aren't covered. What does verification do and why is it secure? Why does it say -that artifact attestations achieve [SLSA v1.0 Build Level 2 and not -L3](https://docs.github.com/en/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds#about-slsa-levels-for-artifact-attestations)? -How could you achieve L3 with artifact attestations? +provides a comprehensive explanation of how Artifact Attestations work. +However, some questions remain unanswered, such as the specific security +measures implemented by the verification process, the reasons behind achieving +[SLSA Build Level +2](https://docs.github.com/en/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds#about-slsa-levels-for-artifact-attestations) +instead of L3, and potential avenues for further improvement. -I’ll do my best to answer some of these questions here, detail why I think -there's still room for improvement, and how we could build more secure -solutions for users of GitHub Actions. But first we need to understand a bit -about how GitHub Artifact Attestations work and their relation to SLSA levels. +I’ll try to shed some light on these aspects, explore areas where enhancements +could be made, and discuss how Artifact Attestations can be leveraged to +achieve SLSA Build Level 3. But first we need to understand its architectural +details and their relationship with SLSA levels. -## Architecture +### Architecture Generating attestations is done using the [`attest-build-provenance`](https://github.com/actions/attest-build-provenance) @@ -40,6 +37,8 @@ GitHub action. Github’s blog post does a good job of explaining how it works s I won’t rehash it fully here. Instead, I’ll summarize the flow and highlight some additional information that will be important later. +![Architecture Diagram](/assets/images/2024-05-23-understanding-github-artifact-attestations/sigstore.png "Architecture Diagram") + 1. `attest-build-provenance` requests an OIDC token from the GitHub OIDC provider. This OIDC token contains [information about the build](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#understanding-the-oidc-token) @@ -47,12 +46,12 @@ some additional information that will be important later. Here's what a typical OIDC token's fields look like: - ```json + ``` { - "aud": "https://github.com/octo-org", + "aud": "https://github.com/octo-org", "iss": "https://token.actions.githubusercontent.com", "job_workflow_ref": "octo-org/octo-automation/.github/workflows/oidc.yml@refs/heads/main", - "runner_environment": "github-hosted" + "runner_environment": "github-hosted", "repository": "octo-org/octo-repo", "sha": "example-sha", "ref": "refs/heads/main", @@ -71,8 +70,8 @@ some additional information that will be important later. 2. The OIDC token is sent to a [Sigstore Fulcio](https://github.com/sigstore/fulcio) server (either the public - instance or GitHub’s private one). [Fulcio can recognize and validate GitHub’s - OIDC + instance or GitHub’s private one). [Fulcio can recognize and validate + GitHub’s OIDC tokens](https://docs.sigstore.dev/certificate_authority/oidc-in-fulcio/#github) and, after verifying its signature, issues a certificate in exchange for the OIDC token. This certificate includes much of the information from the OIDC @@ -80,10 +79,10 @@ some additional information that will be important later. fields](https://github.com/sigstore/fulcio/blob/main/docs/oid-info.md#mapping-oidc-token-claims-to-fulcio-oids) as OID claims. - ```shell + ``` $ openssl x509 -in certificate.crt -text -noout ... - X509v3 extensions: [37/636] + X509v3 extensions: X509v3 Key Usage: critical Digital Signature X509v3 Extended Key Usage: @@ -103,31 +102,32 @@ some additional information that will be important later. 1.3.6.1.4.1.57264.1.4: Test Artifact Attestations 1.3.6.1.4.1.57264.1.5: - ianlewis/gha-artifact-attestations-test + ianlewis/gha-artifact-attestations-test 1.3.6.1.4.1.57264.1.6: - refs/heads/main + refs/heads/main 1.3.6.1.4.1.57264.1.8: - .+https://token.actions.githubusercontent.com + .+https://token.actions.githubusercontent.com 1.3.6.1.4.1.57264.1.9: - .|https://github.com/ianlewis/gha-artifact-attestations-test/.github/workflows/artifact-attestations.basic.yml@refs/heads/main + .|https://github.com/ianlewis/gha-artifact-attestations-test/.github/workflows/artifact-attestations.basic.yml@refs/heads/main 1.3.6.1.4.1.57264.1.10: - .(9e68bb76632788dc01c6596298fb015f46b7fe0f + .(9e68bb76632788dc01c6596298fb015f46b7fe0f 1.3.6.1.4.1.57264.1.11: - github-hosted . + github-hosted . 1.3.6.1.4.1.57264.1.12: - .:https://github.com/ianlewis/gha-artifact-attestations-test + .:https://github.com/ianlewis/gha-artifact-attestations-test + ... ``` -3. A SLSA attestation +3. A SLSA [predicate](https://github.com/in-toto/attestation/blob/main/spec/v1/predicate.md) - is generated and the provenance statement is signed with the returned - certificate’s private key. The resulting signature is combined with the - provenance to create a full attestation bundle and this bundle is recorded in - GitHub’s attestation store. + nis generated and the provenance statement is signed with the returned + ncertificate’s private key. The resulting signature is combined with the + nprovenance to create a full attestation bundle and this bundle is recorded + in GitHub’s attestation store. The SLSA predicate looks something like this: - ```json + ``` { "buildDefinition": { "buildType": "https://slsa-framework.github.io/github-actions-buildtypes/workflow/v1", @@ -165,14 +165,14 @@ some additional information that will be important later. } ``` -I'm leaving out some details but this is the general flow for attestation. So -as a result we have both an attestation bundle in JSON format **and** a -Sigstore certificate with some OID claims set. +I'm leaving out some details but this is the general flow for attestation. So as +a result we have _both_ an attestation bundle in JSON format \_and \_this +includes the Sigstore certificate with some OID claims set. After we have an artifact and attestation, as a user, we need to be able to -verify it before we use it. Verification works something like the following. -The code for this is found in the [`gh attestations verify -command`](https://github.com/cli/cli/tree/trunk/pkg/cmd/attestation/verify) +verify it before we use it. Verification works something like the following. The +code for this is found in the [`gh attestations verify` +command](https://github.com/cli/cli/tree/trunk/pkg/cmd/attestation/verify) for GitHub’s official CLI tool. 1. The attestation is downloaded from the GitHub Attestations API using the @@ -190,13 +190,12 @@ have been omitted below. Next, let's discuss some of the trade-offs of this architecture. - +### A Good User Experience -## A Good User Experience - -By providing a GitHub Action, GitHub gives users flexibility when integrating -this into their GitHub Actions workflows. It’s simple to add a job step to -your workflow and pass it a path to your artifact file. +One of the positive aspects of Artifact Attestations is its user experience. By +providing a GitHub Action, GitHub gives users flexibility when integrating this +into their GitHub Actions workflows. All it takes is to add a job step to your +workflow and pass it a path to your artifact file. ``` - name: Attest Build Provenance @@ -209,14 +208,14 @@ Easy-to-use UX is really important for security because it increases adoption. This can’t be understated and is an often overlooked aspect of security software. -## Why SLSA Build L2? +### Why SLSA Build L2 and not L3? -But if this is a fairly secure solution, why is this SLSA Build L2 and not L3? -The main reason is that, by itself, the `attest-build-provenance` action -doesn’t meet this requirement for [SLSA Build +If this is a fairly secure solution, why is this SLSA Build L2 and not L3? The +main reason is that, by itself, the `attest-build-provenance` action doesn’t +meet this requirement for [SLSA Build L3](https://slsa.dev/spec/v1.0/levels#build-l3-hardened-builds): -prevent secret material used to sign the provenance from being accessible to the user-defined build steps. +_> prevent secret material used to sign the provenance from being accessible to the user-defined build steps._ Because GitHub Actions are run in the same job VM with other build steps there is a chance that the user-defined build steps could access the secret material, @@ -227,109 +226,86 @@ artifact and sign it with the key. However, as we’ll see, this kind of attack is mostly mitigated by using Sigstore. -## SLSA Build L2+? +### SLSA Build L2+? -By using Sigstore’s Fulcio, the certificate used to sign the provenance -contains much of the SLSA predicate's information in its OID claims. These -claims are signed by part of Fulcio instance’s certificate chain and thus -cannot be modified by the user-defined build steps unless the Sigstore instance -or GitHub’s OIDC provider are compromised. +By using Sigstore’s Fulcio, the certificate used to sign the provenance contains +much of the SLSA predicate's information in its OID claims. These claims are +signed by part of Fulcio instance’s certificate chain and thus cannot be +modified by the user-defined build steps unless the Sigstore instance or +GitHub’s OIDC provider are compromised. -So while the SLSA predicate itself might be modified the certificate OID -claims cannot. So GitHub can check the OID claims against the expected values -in order to verify them even though the user-defined build steps had access to -the signing key. So this is why verification doesn’t rely on the predicate -and instead relies on the certificate’s OID claims for verification. +So while the SLSA predicate itself might be modified the certificate OID claims +cannot. So GitHub can check the OID claims against the expected values to verify +them even though the user-defined build steps had access to the signing key. So +this is why verification doesn’t rely on the predicate and instead relies on the +certificate’s OID claims for verification. Some folks have colloquially referred to this combination of Sigstore and SLSA Build L2 as SLSA Build L2+ since it provides some of the benefits of SLSA Build L3 without actually fulfilling all of the requirements of L3. -## Limits of SLSA Build L2+ +### The Limits of SLSA Build L2+ -However, this comes with a caveat. This means that if the user-defined build -steps could have access to the signing keys then **only** the information in -the certificate’s OID claims are trustworthy. No information that isn’t -included in these claims can be included in the SLSA predicate because it can’t -be verified later. +However, this comes with a few caveats. -Crucially this includes values like the GitHub Actions workflow -[`inputs`](https://docs.github.com/en/actions/learn-github-actions/contexts#inputs-context) -and -[`vars`](https://docs.github.com/en/actions/learn-github-actions/contexts#vars-context) -contexts. These include the inputs into a build and could potentially be used -for script injection attacks. While they can’t be used to attack the provenance -itself, they could be used to attack the build without leaving any trace in the -provenance. +**First**, a compromised build with access to signing keys poses the threat of +using the key to sign and [publish malicious packages on a mirror +repository](https://checkmarx.com/blog/over-170k-users-affected-by-attack-using-fake-python-infrastructure/). +Sigstore's Fulcio mitigates this by providing short-lived keys with a validity +of 10 minutes, but attackers could still exfiltrate the key and use the key +within this time period to leave less evidence. -This means that while GitHub Artifact Attestations can be used with policy -engines/tools like Rego, Cue, and OPA, these policies can’t be evaluated on the -build inputs. For example, to verify that the build had no inputs etc. in order -to prevent these kinds of attacks. +**Second**, if user-defined build steps have access to the signing keys, +**only** the information in the certificate's OID claims is trustworthy. +Information not in the OID claims can't be included in the SLSA predicate, +affecting more complex data like GitHub Actions workflow +[inputs](https://docs.github.com/en/actions/learn-github-actions/contexts#inputs-context) +and +[vars](https://docs.github.com/en/actions/learn-github-actions/contexts#vars-context) +contexts. While these can't attack the provenance, they could be used to attack +the build without leaving a trace, making incident response more challenging. -This architecture also relies heavily on Sigstore’s Fulcio Certificate -Authority to map the OID claims. This means that it’s hard to use separate -private PKI, such as static keys, to sign and verify provenance. While this -isn’t likely a problem for Open Source projects, some enterprises have these -kinds of requirements. +**Third**, the architecture heavily relies on Sigstore's Fulcio Certificate +Authority for mapping OID claims, making it difficult to use private PKI to sign +and verify provenance. While this isn't necessarily a significant concern for +open-source projects, some enterprises have such requirements. -## Achieving SLSA Build L3 with GitHub Artifact Attestations +### Achieving SLSA Build L3 with GitHub Artifact Attestations In the documentation [SLSA Build L3 is described as achievable](https://github.blog/2024-05-02-introducing-artifact-attestations-now-in-public-beta/#an-effortless-user-experience) -but it focuses on SLSA Build L2(+) and L3 is left as an exercise for the -reader. So what would it take to achieve SLSA Build L3 with GitHub Artifact +but it focuses on SLSA Build L2(+) and L3 is left as an exercise for the reader. +So what would it take to achieve SLSA Build L3 with GitHub Artifact Attestations? -The solution is somewhat complex so I will just summarize the requirements here -and leave the details for a later blog post. In order to achieve L3 you, at a -minimum, would roughly need to do the following things: - -- The artifact build would need to be done in a separate job from the call to - `attest-build-provenance`. This ensures that the build and provenance signing - happen on [separate virtual - machines](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions#the-components-of-github-actions) - and that the artifact build steps will not have access to the signing - material. This job should **not** have `attestations: write` permissions. -- The `attest-build-provenance` action is passed a path to the artifact. Jobs - execute on separate VMs so the artifact itself would need to be passed from - the build job to the attestation job. This will need to be done by uploading - the artifact file as a [workflow - artifact](https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts) - from the first job and downloading it in the second job. However, this - artifact could be overwritten by concurrently running build steps. So you - will need to take a checksum (sha256 etc.) and pass it from the build job to - the provenance signing job using job inputs/outputs, and verify it after - download. - -## Conclusion +One way that we have used in the +[slsa-github-generator](https://github.com/slsa-framework/slsa-github-generator/tree/main) +project is to use [reusable +workflows](https://docs.github.com/en/actions/using-workflows/reusing-workflows). +This uses the fact that code in reusable workflows are isolated from the main +workflow because they run on jobs executed on [separate virtual +machines](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions#the-components-of-github-actions). + +However, this comes with the downside that it is not as user friendly as a +simple GitHub Action. Passing data, especially files, between jobs is more +complicated and we are sometimes forced to expose that complexity to the user. +Given that there are significant security improvements, I think it’s worth it. + +### Conclusion Trust in GitHub’s Artifact Attestations trust really lies in the Sigstore -certificate and its OID claims. The signed SLSA provenance is really only nice -to have. GitHub ensures that the JSON printed by the `gh` client’s `--format -json` option is trustworthy simply by forbidding values in the SLSA provenance -JSON that are different from the certificate’s OID claims. This means that the -certificate itself effectively functions as the provenance. This is fine, SLSA -doesn’t even mandate that provenance be in SLSA format, but it’s an important -point to understand. - -As an aside, it’s interesting to note that GitHub’s [npm package -provenance](https://github.blog/2023-04-19-introducing-npm-package-provenance/), -which was announced last year, shares many of the same architectural benefits -and shortcomings we’ve discussed here. - -In the future I’d like to see more CI/CD systems that are more conducive to -verifiable software supply chains. - -1. Well defined build inputs and outputs. -2. Builds that are isolated from each other. More build primitives for isolation. -3. Provenance generation that is decoupled from signing -4. More options for verifiable reproducibility. -5. Multi-tenant transparency logs for organizations and private repos - -Maybe one day. - -In the meantime, GitHub’s Artifact attestations are a really exciting new -feature on GitHub and a great step in the right direction. I would strongly -consider integrating it into your workflows, and artifact verification into your -deployments. +certificate and its OID claims so the certificate itself effectively functions +as the provenance. SLSA doesn’t even mandate that provenance be in SLSA format, +but the architecture of Artifact Attestations does make it a bit more +complicated to reason about the security implications. You shouldn't need to +trust the build when creating attestations. + +Artifact attestations are a really exciting new feature on GitHub and a great +step in the right direction. I would strongly consider integrating it into your +workflows, but first take a look at +[slsa-github-generator](https://github.com/slsa-framework/slsa-github-generator/) +and see if SLSA L3 isn’t achievable for your projects. + +_Thanks to [Hayden Blauzvern](https://twitter.com/haydentherapper), [Ramon +Petgrave](https://twitter.com/thePetgrave), and [Laurent +Simon](https://twitter.com/lsim99) for reviewing this post._ From 92db4267c2b3157272e95485c27c06fa12602840 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Mon, 27 May 2024 11:38:47 +0000 Subject: [PATCH 10/23] Add snippet file types Signed-off-by: Ian Lewis --- ...05-23-understanding-github-artifact-attestations.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md index 2d8d6ac..d19f707 100644 --- a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md @@ -46,9 +46,9 @@ some additional information that will be important later. Here's what a typical OIDC token's fields look like: - ``` + ```json { - "aud": "https://github.com/octo-org", + "aud": "https://github.com/octo-org", "iss": "https://token.actions.githubusercontent.com", "job_workflow_ref": "octo-org/octo-automation/.github/workflows/oidc.yml@refs/heads/main", "runner_environment": "github-hosted", @@ -63,7 +63,7 @@ some additional information that will be important later. "run_id": "example-run-id", "run_number": "10", "run_attempt": "2", - "repository_visibility": "private", + "repository_visibility": "private" // ... } ``` @@ -79,7 +79,7 @@ some additional information that will be important later. fields](https://github.com/sigstore/fulcio/blob/main/docs/oid-info.md#mapping-oidc-token-claims-to-fulcio-oids) as OID claims. - ``` + ```shell $ openssl x509 -in certificate.crt -text -noout ... X509v3 extensions: @@ -127,7 +127,7 @@ some additional information that will be important later. The SLSA predicate looks something like this: - ``` + ```json { "buildDefinition": { "buildType": "https://slsa-framework.github.io/github-actions-buildtypes/workflow/v1", From 933edb0ee309c4ed0436a75f4e2af8c1363683ee Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Mon, 27 May 2024 11:40:30 +0000 Subject: [PATCH 11/23] edit Signed-off-by: Ian Lewis --- .../2024-05-23-understanding-github-artifact-attestations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md index d19f707..694ebff 100644 --- a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md @@ -286,7 +286,7 @@ This uses the fact that code in reusable workflows are isolated from the main workflow because they run on jobs executed on [separate virtual machines](https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions#the-components-of-github-actions). -However, this comes with the downside that it is not as user friendly as a +However, this comes with the downside that it is not quite as user friendly as a simple GitHub Action. Passing data, especially files, between jobs is more complicated and we are sometimes forced to expose that complexity to the user. Given that there are significant security improvements, I think it’s worth it. From 24322423aca8f96dd07d0fe2a144e52a48ee4169 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Mon, 27 May 2024 11:41:34 +0000 Subject: [PATCH 12/23] typo Signed-off-by: Ian Lewis --- .../2024-05-23-understanding-github-artifact-attestations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md index 694ebff..ded7204 100644 --- a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md @@ -120,7 +120,7 @@ some additional information that will be important later. 3. A SLSA [predicate](https://github.com/in-toto/attestation/blob/main/spec/v1/predicate.md) - nis generated and the provenance statement is signed with the returned + is generated and the provenance statement is signed with the returned ncertificate’s private key. The resulting signature is combined with the nprovenance to create a full attestation bundle and this bundle is recorded in GitHub’s attestation store. From 568eed81b65e4f8c7ffadf4ddc7818905303f57c Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Mon, 27 May 2024 11:42:00 +0000 Subject: [PATCH 13/23] typo Signed-off-by: Ian Lewis --- .../2024-05-23-understanding-github-artifact-attestations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md index ded7204..683c61a 100644 --- a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md @@ -122,7 +122,7 @@ some additional information that will be important later. [predicate](https://github.com/in-toto/attestation/blob/main/spec/v1/predicate.md) is generated and the provenance statement is signed with the returned ncertificate’s private key. The resulting signature is combined with the - nprovenance to create a full attestation bundle and this bundle is recorded + provenance to create a full attestation bundle and this bundle is recorded in GitHub’s attestation store. The SLSA predicate looks something like this: From 0af6aa31c0efd03cf621193e0a31113680713fff Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Mon, 27 May 2024 11:42:51 +0000 Subject: [PATCH 14/23] typo Signed-off-by: Ian Lewis --- .../2024-05-23-understanding-github-artifact-attestations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md index 683c61a..bac7b85 100644 --- a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-23-understanding-github-artifact-attestations.md @@ -121,7 +121,7 @@ some additional information that will be important later. 3. A SLSA [predicate](https://github.com/in-toto/attestation/blob/main/spec/v1/predicate.md) is generated and the provenance statement is signed with the returned - ncertificate’s private key. The resulting signature is combined with the + certificate’s private key. The resulting signature is combined with the provenance to create a full attestation bundle and this bundle is recorded in GitHub’s attestation store. From 01dfee71a015e6a6f080e0db594f620e439fa52d Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Mon, 27 May 2024 11:46:18 +0000 Subject: [PATCH 15/23] Update publish date Signed-off-by: Ian Lewis --- ...=> 2024-05-30-understanding-github-artifact-attestations.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename en/_posts/{2024-05-23-understanding-github-artifact-attestations.md => 2024-05-30-understanding-github-artifact-attestations.md} (99%) diff --git a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md similarity index 99% rename from en/_posts/2024-05-23-understanding-github-artifact-attestations.md rename to en/_posts/2024-05-30-understanding-github-artifact-attestations.md index bac7b85..9a5fc45 100644 --- a/en/_posts/2024-05-23-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md @@ -1,7 +1,7 @@ --- layout: post title: "Understanding GitHub Artifact Attestations" -date: 2024-05-23 00:00:00 +0000 +date: 2024-05-30 00:00:00 +0000 permalink: /en/understanding-github-artifact-attestations blog: en tags: security slsa From 2c273f61f690d835784924ed14611d5f4d4de8cd Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Thu, 30 May 2024 08:36:00 +0900 Subject: [PATCH 16/23] Update en/_posts/2024-05-30-understanding-github-artifact-attestations.md --- .../2024-05-30-understanding-github-artifact-attestations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/_posts/2024-05-30-understanding-github-artifact-attestations.md b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md index 9a5fc45..8bfbc74 100644 --- a/en/_posts/2024-05-30-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md @@ -166,7 +166,7 @@ some additional information that will be important later. ``` I'm leaving out some details but this is the general flow for attestation. So as -a result we have _both_ an attestation bundle in JSON format \_and \_this +a result we have _both_ an attestation bundle in JSON format *and* this includes the Sigstore certificate with some OID claims set. After we have an artifact and attestation, as a user, we need to be able to From 620f039497fed0520ae0382b17a396bb52ec735d Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Thu, 30 May 2024 08:36:09 +0900 Subject: [PATCH 17/23] Update en/_posts/2024-05-30-understanding-github-artifact-attestations.md --- .../2024-05-30-understanding-github-artifact-attestations.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/en/_posts/2024-05-30-understanding-github-artifact-attestations.md b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md index 8bfbc74..97590e1 100644 --- a/en/_posts/2024-05-30-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md @@ -236,8 +236,8 @@ GitHub’s OIDC provider are compromised. So while the SLSA predicate itself might be modified the certificate OID claims cannot. So GitHub can check the OID claims against the expected values to verify -them even though the user-defined build steps had access to the signing key. So -this is why verification doesn’t rely on the predicate and instead relies on the +them even though the user-defined build steps had access to the signing key. +This is why verification doesn’t rely on the predicate and instead relies on the certificate’s OID claims for verification. Some folks have colloquially referred to this combination of Sigstore and SLSA From f48c7fbee697838aceebe19e3ab7070ce88f111d Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Thu, 30 May 2024 08:36:16 +0900 Subject: [PATCH 18/23] Update en/_posts/2024-05-30-understanding-github-artifact-attestations.md --- .../2024-05-30-understanding-github-artifact-attestations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/_posts/2024-05-30-understanding-github-artifact-attestations.md b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md index 97590e1..1aeff90 100644 --- a/en/_posts/2024-05-30-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md @@ -234,7 +234,7 @@ signed by part of Fulcio instance’s certificate chain and thus cannot be modified by the user-defined build steps unless the Sigstore instance or GitHub’s OIDC provider are compromised. -So while the SLSA predicate itself might be modified the certificate OID claims +While the SLSA predicate itself might be modified the certificate OID claims cannot. So GitHub can check the OID claims against the expected values to verify them even though the user-defined build steps had access to the signing key. This is why verification doesn’t rely on the predicate and instead relies on the From 4f03d896980e3effceca874ede271ad9400b5f62 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Thu, 30 May 2024 08:36:21 +0900 Subject: [PATCH 19/23] Update en/_posts/2024-05-30-understanding-github-artifact-attestations.md --- .../2024-05-30-understanding-github-artifact-attestations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/_posts/2024-05-30-understanding-github-artifact-attestations.md b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md index 1aeff90..b9ad108 100644 --- a/en/_posts/2024-05-30-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md @@ -224,7 +224,7 @@ nefarious purposes. Normally an attacker, by compromising the build, might be able to use this key material to make up their own provenance for a malicious artifact and sign it with the key. -However, as we’ll see, this kind of attack is mostly mitigated by using Sigstore. +However, as we’ll see, this kind of attack is somewhat mitigated by using Sigstore. ### SLSA Build L2+? From 55f62d1cd4abdfbc4654b9e4e4cbaf9f24819a69 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Thu, 30 May 2024 10:33:01 +0900 Subject: [PATCH 20/23] Update en/_posts/2024-05-30-understanding-github-artifact-attestations.md --- .../2024-05-30-understanding-github-artifact-attestations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/_posts/2024-05-30-understanding-github-artifact-attestations.md b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md index b9ad108..9dc13cc 100644 --- a/en/_posts/2024-05-30-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md @@ -166,7 +166,7 @@ some additional information that will be important later. ``` I'm leaving out some details but this is the general flow for attestation. So as -a result we have _both_ an attestation bundle in JSON format *and* this +a result we have *both* an attestation bundle in JSON format *and* this includes the Sigstore certificate with some OID claims set. After we have an artifact and attestation, as a user, we need to be able to From d89effe3faf4589785afeecd0a4ed0a82d0eda80 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Thu, 30 May 2024 01:34:56 +0000 Subject: [PATCH 21/23] Move images Signed-off-by: Ian Lewis --- .../sigstore.excalidraw | 0 .../sigstore.png | Bin ...30-understanding-github-artifact-attestations.md | 4 ++-- 3 files changed, 2 insertions(+), 2 deletions(-) rename assets/images/{2024-05-23-understanding-github-artifact-attestations => 2024-05-30-understanding-github-artifact-attestations}/sigstore.excalidraw (100%) rename assets/images/{2024-05-23-understanding-github-artifact-attestations => 2024-05-30-understanding-github-artifact-attestations}/sigstore.png (100%) diff --git a/assets/images/2024-05-23-understanding-github-artifact-attestations/sigstore.excalidraw b/assets/images/2024-05-30-understanding-github-artifact-attestations/sigstore.excalidraw similarity index 100% rename from assets/images/2024-05-23-understanding-github-artifact-attestations/sigstore.excalidraw rename to assets/images/2024-05-30-understanding-github-artifact-attestations/sigstore.excalidraw diff --git a/assets/images/2024-05-23-understanding-github-artifact-attestations/sigstore.png b/assets/images/2024-05-30-understanding-github-artifact-attestations/sigstore.png similarity index 100% rename from assets/images/2024-05-23-understanding-github-artifact-attestations/sigstore.png rename to assets/images/2024-05-30-understanding-github-artifact-attestations/sigstore.png diff --git a/en/_posts/2024-05-30-understanding-github-artifact-attestations.md b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md index 9dc13cc..50354d7 100644 --- a/en/_posts/2024-05-30-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md @@ -37,7 +37,7 @@ GitHub action. Github’s blog post does a good job of explaining how it works s I won’t rehash it fully here. Instead, I’ll summarize the flow and highlight some additional information that will be important later. -![Architecture Diagram](/assets/images/2024-05-23-understanding-github-artifact-attestations/sigstore.png "Architecture Diagram") +![Architecture Diagram](/assets/images/2024-05-30-understanding-github-artifact-attestations/sigstore.png "Architecture Diagram") 1. `attest-build-provenance` requests an OIDC token from the GitHub OIDC provider. This OIDC token contains [information about the @@ -166,7 +166,7 @@ some additional information that will be important later. ``` I'm leaving out some details but this is the general flow for attestation. So as -a result we have *both* an attestation bundle in JSON format *and* this +a result we have _both_ an attestation bundle in JSON format _and_ this includes the Sigstore certificate with some OID claims set. After we have an artifact and attestation, as a user, we need to be able to From 8b73a5cfdb072ef21851612779425056c6f1744e Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Thu, 30 May 2024 01:44:14 +0000 Subject: [PATCH 22/23] edit Signed-off-by: Ian Lewis --- ...2024-05-30-understanding-github-artifact-attestations.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/en/_posts/2024-05-30-understanding-github-artifact-attestations.md b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md index 50354d7..e9b6dc0 100644 --- a/en/_posts/2024-05-30-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md @@ -184,9 +184,9 @@ for GitHub’s official CLI tool. 3. The expected values for the owner or repo given by the user are matched against the signing certificate’s OID claims. -Notice that nowhere here did we actually use the contents of the SLSA predicate -for verification. I think this is an oversight but we’ll discuss why that might -have been omitted below. +Notice that nowhere here is it actually necessary use the contents of the SLSA +predicate for verification. It isn't really necessary if you are treat the +certificate itself as the provenance. Next, let's discuss some of the trade-offs of this architecture. From dd5c3a69e4aaabc98812206a09b16c3603be1c63 Mon Sep 17 00:00:00 2001 From: Ian Lewis Date: Thu, 30 May 2024 01:50:33 +0000 Subject: [PATCH 23/23] edit Signed-off-by: Ian Lewis --- ...4-05-30-understanding-github-artifact-attestations.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/en/_posts/2024-05-30-understanding-github-artifact-attestations.md b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md index e9b6dc0..825ffe2 100644 --- a/en/_posts/2024-05-30-understanding-github-artifact-attestations.md +++ b/en/_posts/2024-05-30-understanding-github-artifact-attestations.md @@ -210,10 +210,11 @@ software. ### Why SLSA Build L2 and not L3? -If this is a fairly secure solution, why is this SLSA Build L2 and not L3? The -main reason is that, by itself, the `attest-build-provenance` action doesn’t -meet this requirement for [SLSA Build -L3](https://slsa.dev/spec/v1.0/levels#build-l3-hardened-builds): +One downside of the `attest-build-provenance` action is that it only meets the +requirements of SLSA Build L2 when used on its own. + +The main reason is that, by itself, it doesn’t meet this requirement for [SLSA +Build L3](https://slsa.dev/spec/v1.0/levels#build-l3-hardened-builds): _> prevent secret material used to sign the provenance from being accessible to the user-defined build steps._