|
| 1 | +# SLSA Build Attestation |
| 2 | + |
| 3 | +This repository publishes build provenance for release artifacts in |
| 4 | +accordance with [SLSA (Supply-chain Levels for Software Artifacts)][slsa] |
| 5 | +Build specifications. SLSA provenance allows downstream consumers to |
| 6 | +verify that an artifact was built from the expected source repository, |
| 7 | +at the expected commit, by the expected build platform. |
| 8 | + |
| 9 | +## Target Level |
| 10 | + |
| 11 | +**Current target: SLSA Build L2 (achieved today)** |
| 12 | + |
| 13 | +The release pipeline is hosted on GitHub Actions, an isolated build |
| 14 | +platform that is owned and administered by GitHub. Provenance is |
| 15 | +generated automatically for every published release using |
| 16 | +[`slsa-framework/slsa-github-generator`][slsa-gh-gen] and the |
| 17 | +`attest-build-provenance` action. Provenance is signed by a GitHub- |
| 18 | +hosted OIDC token and stored in the [GitHub Artifact Attestations][ghaa] |
| 19 | +log alongside the artifact. |
| 20 | + |
| 21 | +| Requirement | Status | |
| 22 | +| ------------------------------------------- | ------------ | |
| 23 | +| Provenance generated automatically | ✅ L2 | |
| 24 | +| Provenance distributed alongside artifact | ✅ L2 | |
| 25 | +| Build platform hosted and isolated | ✅ L2 | |
| 26 | +| Provenance authenticity (OIDC-signed) | ✅ L2 | |
| 27 | +| Build platform isolated from build request | ⏭ L3 target | |
| 28 | +| Hardened build platform | ⏭ L3 target | |
| 29 | +| Provenance non-forgeable (sigstore/cosign) | ⏭ L3 target | |
| 30 | + |
| 31 | +## Workflow |
| 32 | + |
| 33 | +The CI workflow lives at |
| 34 | +[`.github/workflows/release-attestation.yml`](../.github/workflows/release-attestation.yml) |
| 35 | +and is triggered: |
| 36 | + |
| 37 | +- Automatically on every `release: published` event. |
| 38 | +- Manually via `workflow_dispatch` for ad-hoc provenance generation. |
| 39 | + |
| 40 | +### Build Steps |
| 41 | + |
| 42 | +1. **Checkout** — full history (`fetch-depth: 0`) so the git revision |
| 43 | + can be embedded in provenance. |
| 44 | +2. **Toolchain** — pinned `stable` Rust via |
| 45 | + [`dtolnay/rust-toolchain`][rust-toolchain]. |
| 46 | +3. **Cache** — cargo registry, git index, and `target/` via |
| 47 | + [`Swatinem/rust-cache`][rust-cache]. |
| 48 | +4. **Build** — `cargo build --release --locked --workspace --all-targets`. |
| 49 | +5. **Stage** — collect built executables, source tarball, and a build |
| 50 | + manifest into `release-artifacts/`. |
| 51 | +6. **Upload** — publish `release-artifacts` as a GitHub Actions artifact |
| 52 | + (90 day retention). |
| 53 | +7. **Attest** — generate SLSA Build L2 provenance with |
| 54 | + `slsa-framework/slsa-github-generator/attest-build-provenance@v1`. |
| 55 | + |
| 56 | +## Verification |
| 57 | + |
| 58 | +Consumers can verify a release artifact's provenance using the |
| 59 | +[GitHub CLI][gh-cli]: |
| 60 | + |
| 61 | +```bash |
| 62 | +gh attestation verify <artifact> --owner <org> |
| 63 | +``` |
| 64 | + |
| 65 | +Or with [`cosign`][cosign]: |
| 66 | + |
| 67 | +```bash |
| 68 | +cosign verify-attestation \ |
| 69 | + --certificate-identity-regexp 'https://github.com/slsa-framework/slsa-github-generator' \ |
| 70 | + --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \ |
| 71 | + <artifact> |
| 72 | +``` |
| 73 | + |
| 74 | +The in-toto provenance attestation (`slsa-github-generator/actions/attest-build-provenance`) |
| 75 | +contains: |
| 76 | + |
| 77 | +- `builder.id` — `https://github.com/actions/runner` |
| 78 | +- `invocation.config.source.uri` — repository URL |
| 79 | +- `invocation.config.source.entryPoint` — build workflow path |
| 80 | +- `invocation.config.source.digest.sha1` — git commit SHA |
| 81 | +- `invocation.config.source.ref` — git ref (tag / branch) |
| 82 | +- `metadata.buildInvocationID` — workflow run ID |
| 83 | +- `metadata.completeness.parameters` — whether all inputs are hashed |
| 84 | +- `metadata.completeness.environment` — whether environment is fully captured |
| 85 | + |
| 86 | +## Path to SLSA Build L3 |
| 87 | + |
| 88 | +The current pipeline satisfies L2. To graduate to L3, the following |
| 89 | +additions are required: |
| 90 | + |
| 91 | +1. **Isolated build environment** — move from a hosted runner to |
| 92 | + ephemeral, single-tenant builders (e.g. |
| 93 | + `slsa-framework/slsa-github-generator`'s `generator_containerized_slsa3.yml` |
| 94 | + reusable workflow, or a self-hosted runner with a hardened image). |
| 95 | +2. **Provenance non-forgeability** — the generator workflow re-signs |
| 96 | + provenance with a build-platform-held signing key (sigstore / KMS) |
| 97 | + rather than relying on the GitHub OIDC token alone. |
| 98 | +3. **Provenance transparency log** — the generator publishes |
| 99 | + provenance to a transparency log (e.g. Rekor) so forgery is |
| 100 | + detectable by the wider community. |
| 101 | + |
| 102 | +To upgrade, switch the `attest-build-provenance` step to invoke the |
| 103 | +`slsa-framework/slsa-github-generator/.github/workflows/generator_containerized_slsa3.yml@v2` |
| 104 | +reusable workflow with a build image pinned by digest. The reusable |
| 105 | +workflow handles ephemeral runners, hardened isolation, and |
| 106 | +non-forgeable provenance signing transparently. |
| 107 | + |
| 108 | +## References |
| 109 | + |
| 110 | +- [SLSA Framework][slsa] |
| 111 | +- [`slsa-framework/slsa-github-generator`][slsa-gh-gen] |
| 112 | +- [GitHub Artifact Attestations][ghaa] |
| 113 | +- [GitHub Actions security hardening][ghas] |
| 114 | +- [`dtolnay/rust-toolchain`][rust-toolchain] |
| 115 | +- [`Swatinem/rust-cache`][rust-cache] |
| 116 | +- [`cosign`][cosign] |
| 117 | + |
| 118 | +[slsa]: https://slsa.dev |
| 119 | +[slsa-gh-gen]: https://github.com/slsa-framework/slsa-github-generator |
| 120 | +[ghaa]: https://docs.github.com/en/security/supply-chain-security/artifact-attestations |
| 121 | +[ghas]: https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions |
| 122 | +[gh-cli]: https://cli.github.com |
| 123 | +[cosign]: https://github.com/sigstore/cosign |
| 124 | +[rust-toolchain]: https://github.com/dtolnay/rust-toolchain |
| 125 | +[rust-cache]: https://github.com/Swatinem/rust-cache |
0 commit comments