CoursesSoftware supply chain in depthAdmission & pipeline hardening

Hardening the pipeline

Pin actions by SHA, OIDC, ephemeral runners.

Expert35 min · lesson 15 of 15

The pipeline that builds and signs everything is itself the highest-value target in the supply chain — compromise it and you inherit its trust, its credentials, and its reach into every downstream consumer. The recent wave of CI attacks makes hardening the pipeline non-negotiable.

Lessons from real CI compromises

Codecov’s altered uploader script and the 2025 tj-actions/changed-files compromise showed the pattern: a widely-used build-time component is subverted, and it exfiltrates secrets from every pipeline that runs it. The defenses are concrete. Pin third-party actions to a full commit SHA, never a mutable tag like @v4 that a maintainer or attacker can repoint. Grant each job least-privilege, short-lived credentials — ideally OIDC federation instead of long-lived secrets — so a compromised step reaches little and for little time. Never echo secrets to logs, and scope them to the jobs that need them.

harden the workflow itself
permissions:
contents: read # least privilege by default; elevate per-job only
id-token: write # OIDC for keyless signing / cloud auth (no stored keys)
jobs:
build:
runs-on: ephemeral-runner # fresh, isolated environment per build
steps:
# Pin third-party actions to a full SHA, not a mutable tag:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
# Never: run: echo "$SECRET" → leaks into logs and artifacts

Isolation, review, and closing the loop

Beyond credentials, harden the environment and the process. Run builds on ephemeral, isolated runners so malware cannot persist to the next job or contaminate other builds — which also underpins SLSA’s build isolation. Protect release branches with required review and status checks so a single compromised account cannot push straight to a release. And close the loop: the pipeline should produce the signatures, provenance, and SBOMs from earlier in this course, and a verification gate (admission or release) must enforce them — producing evidence without verifying it protects nothing. A hardened pipeline plus an enforcing gate is the end-to-end assurance the whole course has been building toward.

Hardening the pipeline
credentials
OIDC, short-lived, scoped
no long-lived shared secrets
never log secrets
no echo to build output
integrity
pin actions by SHA
no mutable-tag hijack
ephemeral isolated runners
no persistence/contamination
protected release branches
required review + checks
close the loop
produce + verify evidence
sign/attest AND gate on it
Treat CI as production: least-privilege identity, pinned inputs, isolated runners, reviewed releases — and enforce the evidence it produces.
A mutable-tag action is remote code execution in your pipeline
Referencing a third-party action by @v4 runs whatever that tag points to now — if the maintainer is compromised or malicious, their code executes with your pipeline’s secrets and permissions, as the tj-actions incident showed. Pin every third-party action to a full commit SHA and review updates deliberately.