ADR-0032 — GitHub Actions CI + OIDC keyless + supply-chain security
- Status: Deferred
- Date: 2026-06-11
- Related: platform/07 CI/CD, platform/01 containers, ADR-0028
V1 Freeze (2026-06-12): Deferred. V1 CI = build/test/lint. SBOM/trivy/cosign/SLSA re-open at P4.
Context
CI must build, test, and publish artifacts safely. Two recurring risks: long-lived credentials in CI (cloud keys, signing keys, registry creds — prime theft targets) and unverifiable artifacts (no provenance, unsigned images, unknown dependencies) — now a regulatory concern (EO 14028, EU CRA). CI must also not hold cluster credentials (ADR-0028).
Decision
GitHub Actions for CI, with a hard CI/CD boundary and supply-chain security built in:
- CI ends at “signed image pushed + GitOps PR opened” — deployment is ArgoCD’s pull-based job; CI never holds a kubeconfig.
- OIDC everywhere, no long-lived secrets: GitHub OIDC → cloud IAM role (registry
push,
tofu plan) and → Fulcio for keyless cosign signing (id-token: write; signatures logged in Rekor). - Every image carries: an SBOM (syft), a vuln scan gate (trivy/grype), a keyless signature (cosign), and SLSA provenance (in-toto attestation).
- Admission verification: clusters run only images with a valid signature + provenance (policy-controller/Kyverno).
- Monorepo ergonomics: path-filtered builds, reusable workflows, layer/dep caching,
multi-arch (amd64+arm64); pinned action SHAs, least-privilege
GITHUB_TOKEN.
Consequences
Positive
- No durable credentials in CI (OIDC + keyless) → drastically smaller attack surface.
- Artifacts are attestable end-to-end (SBOM + signature + provenance + Rekor) and verified at admission — a complete supply-chain chain.
- Fast incremental builds via path filters + caching.
Negative / costs
- Full supply-chain adds CI time/complexity (mostly cached/parallelized).
id-token: writeis restricted on PRs → signing happens post-merge (a GitHub constraint we design around).
Alternatives considered
- CI deploys directly (push CD): CI holds cluster creds; rejected (ADR-0028).
- Long-lived registry/cloud/signing keys: the exact thing OIDC/keyless eliminate.
- Keyed cosign signing: a key to rotate/leak; keyless preferred.
- Other CI (GitLab/Buildkite): equivalent OIDC support; GitHub Actions chosen for repo proximity.
Scaling
Self-hosted/larger runners (incl. arm64) + aggressive caching + path-filtered matrices scale build throughput; small signed images reduce registry/egress cost (platform/01).