Supply Chain Security
Securing the software supply chain from source to production.
Threat Model
Source Code → Build → Artifact → Registry → Deploy → Runtime
│ │ │ │ │ │
Injection Compromise Tampering Poisoning Drift Exploit
Key Risks
| Stage |
Risks |
| Source |
Malicious commits, compromised accounts, CI config tampering |
| Dependencies |
Typosquatting, dependency confusion, malicious packages |
| Build |
Compromised build agents, injected artifacts, provenance forgery |
| Artifact |
Unsigned images, tampered layers, base image vulnerabilities |
| Registry |
Unauthorized pushes, tag mutation, registry compromise |
| Deploy |
Drift from tested artifact, unauthorized changes, config injection |
| Runtime |
Vulnerable components, privilege escalation, supply chain exploits |
SLSA (Supply Chain Levels for Software Artifacts)
| Level |
Requirements |
Guarantees |
| SLSA 1 |
Build scripted; provenance generated |
Build process documented |
| SLSA 2 |
SLSA 1 + hosted build service; tamper-resistant provenance |
Tamper-resistant build |
| SLSA 3 |
SLSA 2 + hardened build platform; non-falsifiable provenance |
Strong tamper resistance |
| SLSA 4 |
SLSA 3 + two-person review; hermetic builds; reproducible |
Highest confidence |
Start at SLSA 1 — automate build, generate provenance. Progress incrementally.
Source Code Security
Repository Protection
- Branch protection — Require PR reviews, status checks, signed commits
- Signed commits —
git commit -S; verify with git log --show-signature
- CODEOWNERS — Mandatory review for sensitive paths
- Secret scanning — Push protection (GitHub, GitLab, Gitleaks in CI)
- Dependency review — Analyze dependency changes in PRs
Access Control
- Least privilege — Read/write/admin per role
- 2FA required — All contributors
- SSO + SCIM — Centralized identity; auto-provision/deprovision
- Audit logs — Monitor for anomalous activity
Dependency Management
Lockfiles (Mandatory)
- Commit lockfiles —
package-lock.json, yarn.lock, Cargo.lock, go.sum, pom.xml (with versions)
- No floating versions — Exact versions only
- Automated updates — Dependabot, Renovate, Renovate Bot with PRs
Private Registry / Proxy
- Mirror public registries — npm, PyPI, Maven Central, crates.io, Docker Hub
- Blocks typosquatting — Internal packages can't be hijacked
- Scan on proxy — Malware, license, vulnerability scanning at ingest
- Tools — Nexus, Artifactory, Verdaccio, DevPi, ghcr.io
Dependency Pinning Strategy
# Bad: Floating versions
dependencies:
requests: "*"
lodash: "^4.0.0"
# Good: Exact versions with automated updates
dependencies:
requests: "2.31.0"
lodash: "4.17.21"
SBOM (Software Bill of Materials)
- Generate at build — SPDX or CycloneDX format
- Include transitive deps — Full dependency tree
- Sign SBOM — Verify integrity
- Tools — Syft, Trivy, CycloneDX CLI, SPDX tools
- Consume — Vulnerability scanning, license compliance
Build Security
Hermetic Builds
- Reproducible — Same inputs = same outputs (bit-for-bit)
- No network access — All deps pre-fetched; no external calls
- Fixed toolchain — Pinned compiler, linker, base image versions
- Isolated environment — Clean per build; no host leakage
Build Provenance
{
"buildType": "https://github.com/slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.4.0",
"externalParameters": {
"source": {
"uri": "github.com/org/repo",
"digest": "sha256:abc123..."
}
},
"internalParameters": {
"builder": {
"id": "github-hosted"
}
},
"materials": [
{"uri": "github.com/org/repo", "digest": {"sha256": "abc123..."}}
]
}
CI/CD Hardening
- Ephemeral runners — Fresh VM/container per job
- No secrets in logs — Masking + secret scanning
- Pin action versions —
uses: actions/checkout@v4.1.1 (not @v4)
- Least privilege tokens —
permissions: contents: read per job
- OIDC for cloud auth — No long-lived cloud keys
Artifact Security
Container Images
- Minimal base images —
distroless, chainguard, alpine, scratch
- Multi-stage builds — Build in SDK image; copy to minimal runtime
- No secrets in layers — Build args ≠ runtime secrets
- Scan every layer — Trivy, Grype, Snyk, Docker Scout
- Sign images — Cosign/Sigstore; verify on deploy
Image Signing (Cosign/Sigstore)
# Sign
cosign sign --yes ghcr.io/org/app:v1.2.3
# Verify
cosign verify --certificate-identity-regexp=".*" \
--certificate-oidc-issuer-regexp=".*" \
ghcr.io/org/app:v1.2.3
SBOM in Image
# Attach SBOM as layer
COPY --from=builder /app/sbom.spdx.json /sbom.spdx.json
Registry Security
Access Control
- Scoped tokens — Read-only for CI; write-only for release pipeline
- Immutable tags — Prevent
latest overwrite; enforce semver tags
- Vulnerability scanning — Block critical vulns on push
- Image promotion — Dev → Staging → Prod via copy (not rebuild)
Admission Control
- Policy engine — Kyverno, OPA Gatekeeper, Kyverno
- Require signatures — Only signed images deploy
- Require SLSA provenance — Verify build integrity
- Block vulnerable images — Admission webhook checks scanner results
Deploy Security
GitOps (ArgoCD / Flux)
- Declarative desired state — Git = source of truth
- Automated sync — Drift detection + auto-remediation
- PR-based changes — All changes reviewed
- Audit trail — Every deploy traceable to commit
Runtime Verification
- Image digest pinning — Deploy by
sha256:..., not tag
- Admission policies — Signed, scanned, SLSA-verified
- Runtime security — Falco, Tetragon, Tracee (behavioral detection)
- Drift detection — Compare running vs desired state
Vulnerability Management
Scanning Layers
| Layer |
Tool Examples |
When |
| Source |
SAST (CodeQL, Semgrep), Secret scanning |
PR, commit |
| Dependencies |
SCA (Dependabot, Renovate, OWASP Dep Check) |
PR, scheduled |
| Container |
Trivy, Grype, Syft, Docker Scout |
Build, registry |
| Runtime |
Falco, Tetragon, cloud provider tools |
Continuous |
- Detect → 2. Triage (exploitable? reachable?) → 3. Fix/mitigate → 4. Verify → 5. Deploy
Prioritization
- Reachability analysis — Is vulnerable code actually called?
- Exploit availability — Known exploit in wild?
- Business criticality — Internet-facing? PII handling?
- Fix availability — Patch exists? Version bump?
| Category |
Tools |
| SBOM |
Syft, Trivy, CycloneDX, SPDX, bom |
| Signing |
Cosign, Sigstore, Notary, GPG |
| Verification |
Cosign, SLSA Verifier, Rekor (transparency log) |
| Policy |
Kyverno, OPA Gatekeeper, Conftest |
| Scanning |
Trivy, Grype, Snyk, Aqua, Prisma, Dockle |
| CI/CD |
GitHub Actions, GitLab CI, Tekton, ArgoCD, Flux |
| Runtime |
Falco, Tetragon, Tracee, Cilium, KubeArmor |
Checklist: Minimum Viable Supply Chain Security
- [ ] Branch protection + required reviews + signed commits
- [ ] Secret scanning on push + in CI
- [ ] Lockfiles committed + automated dependency updates
- [ ] Private registry/proxy for all package managers
- [ ] SBOM generated + signed at every build
- [ ] Container images scanned (base + app layers)
- [ ] Images signed (Cosign) + verified on deploy
- [ ] Admission control: require signatures + scan pass
- [ ] GitOps deploy with drift detection
- [ ] Runtime security monitoring (Falco)
- [ ] Vulnerability remediation SLA defined + tracked
- Secure Coding — Application-level security
- Cryptography — Signing, verification
- CI CD Best Practices — Pipeline security
- Infrastructure as Code — IaC security
- Observability — Runtime threat detection
Sources: SLSA Framework, NIST SSDF, CNCF Software Supply Chain Best Practices, Sigstore/Cosign, OWASP SCVS, Google Supply Chain Security, Microsoft SDL, AWS Software Supply Chain