ADR-0012: SLSA Build Level 3 via Reusable Release Build Workflow¶
Date: 2026-10-16
Status¶
Accepted (2026-10-18)
This record proposes upgrading the release pipeline to SLSA Build Level 3 compliance by separating release compilation, provenance attestation, and signing into an isolated reusable GitHub Actions workflow (release-build.yml), called by the entrypoint publish-release.yml.
Context¶
Prior to this decision, .github/workflows/publish-release.yml executed the entire kernel release lifecycle within a single workflow: preflight authorization checks, compilation and boot smoke tests, artifact gating, SBOM generation, keyless cosign signing over SHA256SUMS, and asset upload.
While the build container ran with least privileges and checkout mounted read-only, the workflow lacked formal SLSA Build Level 3 isolation:
- No reusable workflow boundary separated build execution from caller authority.
- Build provenance was not cryptographically attested via an immutable SLSA v1.0 attestation predicate (
actions/attest-build-provenance). - The cosign signer identity was tied directly to
publish-release.yml, preventing dual-verification with cryptographic isolation. - Downstream consumers and repository gates had to record a HISS-11 exception for
publish-release.yml.
To reach SLSA Build Level 3, GitHub Actions requires:
- An isolated, reusable workflow (
release-build.yml) triggered viaworkflow_call. - Build provenance attested inside the build job before artifacts are handed over to any publishing or distribution step.
- The build job must generate and attest artifacts without downloading or restoring unverified blobs from external caches or caller inputs.
- Verification tooling must accept the legacy identity for historical releases while enforcing the new reusable workflow identity for all subsequent releases.
Decision¶
-
Reusable Build Workflow (
release-build.yml): Implement.github/workflows/release-build.ymlwithon: workflow_call, top-levelpermissions: contents: read, and a dedicatedbuildjob withpermissions: contents: read, actions: read, id-token: write, attestations: write. Move kernel resolution, container build, QEMU boot test, artifact gating, SBOM generation, SLSA provenance attestation, and cosign signing into this job. -
In-Job SLSA v1.0 Build Provenance Attestation: After
SHA256SUMSis computed over publishable packages, kernel image, configuration, and SBOMs, invokeactions/attest-build-provenance@v4withsubject-pathmatching all publishable release files. Copy the resulting attestation bundle tooutput/kernel-<stream>.provenance.sigstore.json. The provenance bundle is published as a release asset but excluded fromSHA256SUMS, mirroring the manifest contract. -
In-Job Cosign Signing and Verification: Cosign signs
SHA256SUMSwith keyless OIDC credentials and immediately verifies the signature in-job against the new identity:https://github.com/${GITHUB_REPOSITORY}/.github/workflows/release-build.yml@${GITHUB_REF}. -
Caller Workflow Separation (
publish-release.yml):publish-release.ymlretains its name and triggers, acting solely as an orchestration caller: preflightjob: verifies theKERNEL_FORGE_TOKENdispatch secret withcontents: read.buildjob: callsrelease-build.ymlwith OIDC and attestation write permissions.-
publishjob: runs withcontents: writeONLY (noid-tokenorattestationspermissions), downloads verified build artifacts, publishes them to GitHub Releases, and dispatches downstream notification tocordanaLLM/imago. -
Dual Signer Identity Verification (
release-signers.json): Record the 20 legacy release tags inrelease-signers.json. Implementscripts/release_signer_identity.pyto resolve the expected identity: legacy workflow for the 20 historical tags, reusable workflow for all subsequent tags. Wire this resolver intoscripts/verify-release.sh,.github/workflows/package-lifecycle.yml, and.github/workflows/openzfs-module.yml. -
HISS-11 Compliance: Remove the HISS-11 exception for
publish-release.ymlfrom.standards.yaml.
Consequences¶
Positive¶
- Reaches full SLSA Build Level 3 provenance for all published kernel releases.
- Publishing jobs no longer hold
id-token: writeauthority, preventing credential escalation during asset upload. - Full backwards compatibility with all 20 historical releases is preserved without pattern wildcards or security downgrades.
- Attestation bundles can be verified by adopters via standard tooling:
gh attestation verify <file> -R cordanaLLM/nucleus.
Neutral¶
- An additional asset (
kernel-<stream>.provenance.sigstore.json) is published with each release, bringing total release assets from 10 to 11. - Release verification scripts require
release_signer_identity.pyandrelease-signers.json.