Most organisations cannot prove where their software came from, what is inside it, or that the build that produced it was not tampered with. Attackers know this, which is why stolen publishing tokens, poisoned GitHub Actions and hijacked maintainer accounts now feature in most major supply chain incidents. This five-level model from NHI Mgmt Group describes how software supply chain security matures from Ad hoc to Optimised across seven capability areas, mapped to SLSA, the NIST SSDF and OpenSSF S2C2F. It is written for AppSec, platform and DevSecOps leads who need to score their current state and agree a target.
Key takeaways
- Five levels, seven areas. The levels are Ad hoc, Developing, Defined, Managed and Optimised, scored separately for dependencies, source and build integrity, provenance, SBOM, signing, CI/CD identity and secrets, and third-party code.
- Level 3 is the first serious target. Defined means a hosted build platform, signed provenance (SLSA Build L2), an SBOM for every release and no long-lived publishing tokens.
- Identity is the weakest link. Most recent package compromises started with a stolen token or maintainer account, not a code flaw, so CI/CD identity often caps your overall level.
- Producing evidence is not the same as checking it. Provenance, signatures and SBOMs only reduce risk when something verifies them at deploy or ingest time, which is the jump from Level 3 to Level 4.
- Score the weakest area, not the average. Attackers take the easiest path.
The five levels
| Level | Name | What it looks like | Rough external equivalent |
|---|---|---|---|
| 1 | Ad hoc | Floating dependency versions from public registries, builds on laptops or unmanaged servers, no SBOM or signing, publishing tokens in CI variables. | SLSA Build L0; below S2C2F L1 |
| 2 | Developing | Lockfiles and software composition analysis (SCA) in place, CI generates some build metadata, secrets scanning on, an SBOM produced for some products. Coverage is partial and nobody acts on the output consistently. | SLSA Build L1; S2C2F L1; SLSA Source L1 to L2 |
| 3 | Defined | Policy covers dependency intake, build, release and signing. All releases build on a hosted platform that signs provenance. Branch protection and review are enforced. SBOMs ship with every release. Publishing uses OIDC federation rather than stored tokens. | SLSA Build L2; S2C2F L2; SLSA Source L3 |
| 4 | Managed | Hardened, isolated builds. Admission and ingest controls verify signatures and provenance before anything runs. Dependencies come through an internal proxy with policy. Metrics drive decisions. | SLSA Build L3; S2C2F L3; SLSA Source L4 |
| 5 | Optimised | Verification is continuous and automatic. Critical open source is rebuilt on trusted infrastructure, fixes are upstreamed, CI identities are ephemeral and task-scoped, and supplier evidence is checked as routinely as your own. | SLSA Build L3 everywhere; S2C2F L4 |
The equivalence column is an NHI Mgmt Group mapping to help orientation, not an official crosswalk. SLSA v1.2 is the current approved specification and defines a Build track (L0 to L3) and a Source track (L1 Version controlled, L2 History and Provenance, L3 Continuous technical controls, L4 Two-party review). See the SLSA and Build Provenance Guide.
Capability areas
| Area | Level 1 Ad hoc | Level 3 Defined | Level 5 Optimised | Framework anchors |
|---|---|---|---|---|
| Dependencies | Floating versions, direct registry access, install scripts run with secrets present | Lockfiles everywhere, SCA gating on severity, scoped private packages, update SLAs | Internal proxy with policy, malicious package detection, critical packages rebuilt from source | S2C2F ING, SCA, UPD, ENF, REB; NIST SR-3 |
| Source and build integrity | Direct pushes to main, builds on laptops or shared servers | Branch protection, mandatory review, hosted CI, ephemeral runners for releases | Two-party review on all release paths, isolated hardened builds, reproducible builds for critical components | SLSA Source L3 to L4; SSDF PS.1, PW.6; SA-15 |
| Provenance | None | Platform-generated, signed provenance for every release (SLSA Build L2) | Build L3 provenance verified automatically at deploy and on consumed packages | SLSA Build track; NIST SR-4 |
| SBOM | None, or produced once for an audit | SPDX or CycloneDX SBOM generated in the build for every release and stored with the artefact | SBOMs from suppliers ingested, joined with VEX and vulnerability data, queried during incidents | CISA minimum elements; ID.AM-02 |
| Signing | Unsigned artefacts, or a long-lived key on a build server | All release artefacts and container images signed; keys in HSM/KMS or keyless via Sigstore | Signature and identity policy enforced at admission; transparency log monitored for your identities | NIST SI-7, SR-11; SSDF PS.2 |
| CI/CD identity and secrets | Personal access tokens, shared deploy keys, registry tokens in CI variables | OIDC federation to cloud and registries, least-privilege workflow tokens, actions pinned by SHA | Ephemeral, per-job identities only; no standing publishing credentials; anomaly detection on CI identities | NIST IA-5, AC-6; PR.AA-05 |
| Third-party code | Unreviewed actions, plugins and build tools from anywhere | Allowlist of CI actions and plugins, supplier security requirements in contracts | Supplier provenance and SBOM verified on intake; continuous supplier monitoring | GV.SC-05, GV.SC-07; NIST SA-9 |
What changes at each step
- Provenance: SLSA Build L1 means provenance exists but may be incomplete or unsigned. L2 requires a hosted platform that signs it and consumers that validate it. L3 adds hardened builds where runs cannot influence each other and the signing secret is not reachable from user-defined build steps.
- SBOM: CISA published draft 2025 Minimum Elements for an SBOM for public comment (comments closed 3 October 2025), adding component hash, license, tool name and generation context to the 2021 NTIA baseline. At the time of writing we could not confirm a final version, so treat the draft fields as the likely direction. See the SBOM Guide.
- Signing: with Sigstore, Cosign signs using an ephemeral key, Fulcio issues a short-lived certificate bound to an OIDC identity such as a CI workflow, and Rekor records the event in an append-only transparency log. There is no long-lived signing key to steal.
- Publishing identity: PyPI Trusted Publishing exchanges a CI OIDC token for a project-scoped API token valid for 15 minutes. A leftover static token is exactly what turned an Actions injection into a malicious release in the Ultralytics PyPI compromise.
Self-assessment questions
Score each area at the highest level you meet across most production software. A control on paper, or on one flagship repository, is Level 2.
- Dependencies: could a new public package with the same name as an internal one end up in your build? How long does a critical dependency fix take to reach production?
- Source: can any single account push code to a release branch and trigger a production deployment without a second person?
- Build: do release builds run on ephemeral hosted runners, and can one job read another job's workspace or cache?
- Provenance: for a binary running in production today, can you show signed provenance naming the source commit and build platform, and does anything check it before deploy?
- SBOM: when the next XZ-style backdoor is announced, how many minutes will it take to list every affected product? See the XZ Utils backdoor.
- Signing: where do your signing keys live, who can use them, and would you notice a signature made with your identity that you did not expect?
- CI/CD identity: how many long-lived tokens can publish packages, push images or deploy to cloud, and how many are tied to a person rather than a workflow?
- Third-party code: which third-party GitHub Actions or CI plugins run with access to secrets, and are they pinned to a commit SHA?
Moving up: roadmap
From Ad hoc to Developing (first 90 days)
- Inventory pipelines, registries and publishing credentials; turn on secrets scanning and push protection.
- Commit lockfiles and run SCA on every pull request, in report-only mode first to size the backlog.
- Run the OpenSSF Scorecard against your own and your most critical upstream projects to get a baseline. See the OpenSSF Scorecard Guide.
- Revoke unused publishing and deploy tokens.
From Developing to Defined
- Adopt the NIST SSDF (SP 800-218 v1.1, with Rev. 1 in draft since December 2025) as the policy baseline across its PO, PS, PW and RV groups. See the NIST SSDF Guide.
- Move every release build onto a hosted platform that emits signed provenance (SLSA Build L2), and generate an SBOM in the same job.
- Enforce branch protection and review on release branches; remove standing admin bypasses.
- Replace stored cloud and registry credentials with OIDC federation; set workflow token permissions to read-only by default and pin third-party actions to full commit SHAs. See the CI/CD Pipeline Identity Security Guide.
- Sign all release artefacts and images.
From Defined to Managed
- Turn verification on: admission policy that rejects unsigned images or missing provenance. Run in audit mode first, review rejections, then enforce per environment with a logged, expiring break-glass exception.
- Route all package downloads through an internal proxy with policy (S2C2F L2 to L3) and block install scripts from reaching secrets.
- Harden builds to SLSA Build L3: isolated runs, signing material out of reach of build steps.
- Measure and report the metrics below monthly.
From Managed to Optimised
- Rebuild your most critical open source dependencies from source on trusted infrastructure and contribute fixes upstream (S2C2F L4).
- Require provenance and SBOMs from suppliers and verify them on intake. See the Software Supply Chain Security Buyer's Guide.
- Monitor transparency logs and registry events for your identities and package names.
Metrics that show progress
| Metric | Level 3 target | Level 4 target |
|---|---|---|
| Releases with signed provenance | 100% of releases | 100%, verified at deploy |
| Long-lived publishing or deploy tokens | Inventoried, each with owner and expiry | Zero; OIDC only |
| Third-party actions pinned by SHA | All in release workflows | All workflows, change alerts on |
| Critical dependency fix time | Within agreed SLA | Tracked and trending down |
| Time to list products affected by a new CVE | Under one day | Under one hour from SBOM query |
| Admission rejections for unsigned artefacts | Measured in audit mode | Enforced, exceptions expire |
Practitioner checklist
- Score all seven areas separately and record evidence for each score.
- Set Level 3 as the first target for every product that ships externally.
- Remove every long-lived publishing token you can replace with OIDC trusted publishing.
- Pin third-party CI actions and plugins to commit SHAs and restrict which can run.
- Generate SBOMs and signed provenance in the build job, not afterwards.
- Enforce verification in audit mode first, then per environment, with an expiring break-glass path.
- Route dependencies through a proxy and keep install scripts away from secrets.
- Reassess every six months and after any supply chain incident. See the Supply Chain Compromise Response Playbook.
Standards and references
- OpenSSF: SLSA Specification v1.2
- OpenSSF: SLSA Source Track Requirements
- NIST: SP 800-218 Secure Software Development Framework v1.1
- OpenSSF: Secure Supply Chain Consumption Framework (S2C2F)
- CISA: Draft 2025 Minimum Elements for a Software Bill of Materials
- NIST: SP 800-53 Rev. 5
- Sigstore: Overview
- PyPI: Trusted Publishers
Related NHI Mgmt Group resources: Software Supply Chain Security Guide · Top 10 Supply Chain Attacks · Secrets Management Maturity Model · CI/CD Security Guide