Back to glossary

NIST Secure Software Development Framework (SSDF)

The NIST SSDF (SP 800-218) is NIST's set of outcome-based secure software development practices and tasks, grouped into PO, PS, PW, and RV.

Also known as NIST SSDF, NIST SP 800-218, SP 800-218, SSDF 1.1, SSDF 1.2

The NIST Secure Software Development Framework (SSDF), published as NIST SP 800-218, is a set of outcome-based practices for building software securely. Version 1.1 defines 19 practices and 42 tasks in four groups: Prepare the Organization, Protect the Software, Produce Well-Secured Software, and Respond to Vulnerabilities. U.S. federal software attestation was built on the SSDF.

An SSDF task names an outcome, never a tool. Task PW.4.4 says to verify that third-party components keep meeting your requirements throughout their life cycles, and leaves the method to you. From 2024 until January 2026, federal software suppliers had a CEO or designee sign a form attesting to a subset of these tasks. That form is now optional, and the framework itself is mid-revision: SSDF 1.2 has been a public draft since December 17, 2025.

Our position: the SSDF is the best shared vocabulary the industry has for secure development, but its dependency tasks aim at the wrong threat. The SSDF's examples for third-party code talk about known vulnerabilities, integrity checks, and provenance. In May 2026, the TanStack compromise put 84 malicious package versions on npm, and they passed all three. Catching them required reading what the code did.

What is the NIST SSDF?

#

The NIST SSDF is a catalog of secure development outcomes from the National Institute of Standards and Technology, written abstractly enough to bolt onto any development lifecycle. It prescribes no tools, languages, or processes. NIST is explicit about that: "The intention of the SSDF is not to create a checklist to follow."

NIST published the first SSDF white paper in April 2020. Executive Order 14028, signed May 12, 2021, directed NIST to issue secure development guidance, and SP 800-218 version 1.1 followed on February 3, 2022. A community profile for generative AI and dual-use foundation models, SP 800-218A, followed on July 26, 2024.

Each SSDF task is one row with four columns. Here is task PW.4.4, the one that governs your dependencies after you adopt them:

ColumnPW.4.4 in SSDF 1.1
PracticePW.4: Reuse Existing, Well-Secured Software When Feasible Instead of Duplicating Functionality
TaskVerify that acquired commercial, open-source, and all other third-party software components comply with the requirements, as defined by the organization, throughout their life cycles.
Notional implementation examplesExample 1: "Regularly check whether there are publicly known vulnerabilities in the software modules and services." Example 6: "Confirm the integrity of software components through digital signatures or other mechanisms."
ReferencesMappings to other standards, such as NIST SP 800-53 and SP 800-161

The examples are notional. A team can satisfy PW.4.4 with a weekly CVE scan or with full behavioral analysis of every new version, and the SSDF does not rank the two. That flexibility is why the SSDF fits every organization, and also why claiming conformance says little about what a team actually checks.

The SSDF is narrower than a secure software development lifecycle program. A lifecycle model says when work happens. The SSDF says which security outcomes must exist somewhere in it.

What are the core practices in the NIST SSDF?

#

The core practices in the NIST SSDF fall into four groups, identified by two-letter prefixes:

  • PO, Prepare the Organization: requirements, roles, toolchains, security check criteria, and hardened development environments.
  • PS, Protect the Software: access control over code, release integrity, and archived releases with provenance.
  • PW, Produce Well-Secured Software: design review, component reuse, secure coding, build hardening, code review, testing, and secure defaults.
  • RV, Respond to Vulnerabilities: finding vulnerabilities, remediating them, and analyzing root causes.
GroupPractices in SSDF 1.1TasksAdded in the 1.2 draft
POPO.1 Define security requirements; PO.2 Roles and responsibilities; PO.3 Supporting toolchains; PO.4 Criteria for security checks; PO.5 Secure development environments13PO.6 Continuous process improvement (3 tasks)
PSPS.1 Protect all forms of code; PS.2 Verify release integrity; PS.3 Archive and protect each release4PS.4 Robust and reliable updates (4 tasks)
PWPW.1 Secure design; PW.2 Design review; PW.4 Reuse well-secured software; PW.5 Secure coding; PW.6 Secure build configuration; PW.7 Code review and analysis; PW.8 Test executable code; PW.9 Secure defaults16None
RVRV.1 Identify and confirm vulnerabilities; RV.2 Assess, prioritize, and remediate; RV.3 Root cause analysis9None
Total19 practices422 practices, 7 tasks

The SSDF's IDs have gaps on purpose. PW.3, "Verify Third-Party Software Complies with Security Requirements," was retired in version 1.1. Its tasks moved to PO.1.3 and PW.4.4, and the old IDs stay reserved so existing mappings do not break. Third-party code touches five tasks: PO.1.3, PW.4.1, PW.4.4, PS.3.2, and RV.1.1.

Where open source dependencies sit in the SSDF

#

Open source dependencies sit in the SSDF as an obligation on the consumer, never on the maintainer. PO.1.3 tells you to communicate requirements "to all third parties who will provide commercial software components." Nobody negotiates requirements with a volunteer who maintains a parser on npm. For open source, the SSDF falls back on PW.4.1, acquire well-secured components, and PW.4.4, keep verifying them.

The federal attestation form encoded that split. The CISA Secure Software Development Attestation Form excluded "third-party open source and proprietary components incorporated into the software end product" from its scope. Its second attestation still asked producers for a good-faith effort to secure "internal code and third-party components." Producers attested to their process for handling code they did not write. The open source authors attested to nothing.

The evidence the SSDF suggests for components is provenance and integrity data. PS.3.2 asks producers to "collect, safeguard, maintain, and share provenance data for all components of each software release," naming a software bill of materials (SBOM) as the example. On npm, the closest component-level artifact is a Sigstore provenance attestation. Some packages ship one and some do not:

Bash
$ curl -s https://registry.npmjs.org/semver/7.7.2 | jq '.dist.attestations'
{
  "url": "https://registry.npmjs.org/-/npm/v1/attestations/semver@7.7.2",
  "provenance": {
    "predicateType": "https://slsa.dev/provenance/v1"
  }
}

$ curl -s https://registry.npmjs.org/chalk/5.4.1 | jq '.dist.attestations'
null

Decoding the semver attestation shows what provenance actually asserts: which repository, workflow file, commit, and CI run produced the tarball.

Bash
$ curl -s https://registry.npmjs.org/-/npm/v1/attestations/semver@7.7.2 \
  | jq -r '.attestations[] | select(.predicateType=="https://slsa.dev/provenance/v1")
           | .bundle.dsseEnvelope.payload' | base64 -d \
  | jq '{subject: .subject[0].name,
         workflow: .predicate.buildDefinition.externalParameters.workflow,
         commit: .predicate.buildDefinition.resolvedDependencies[0].digest.gitCommit,
         run: .predicate.runDetails.metadata.invocationId}'
{
  "subject": "pkg:npm/semver@7.7.2",
  "workflow": {
    "ref": "refs/heads/main",
    "repository": "https://github.com/npm/node-semver",
    "path": ".github/workflows/release.yml"
  },
  "commit": "281055e7716ef0415a8826972471331989ede58c",
  "run": "https://github.com/npm/node-semver/actions/runs/14978088339/attempts/1"
}

As of October 18, 2026, none of the 45 published versions of chalk carries a provenance attestation. All 45 have the registry's ECDSA signature, which proves only that the registry served what was uploaded. The gap is normal, not an outlier. We installed express@5.3.0 into an empty project and checked every resolved package against the registry:

Bash
$ npm install --ignore-scripts express@5.3.0
$ node -e '
const lock = require("./package-lock.json");
(async () => {
  let n = 0, prov = 0, sig = 0;
  for (const [path, { version }] of Object.entries(lock.packages)) {
    if (!path.startsWith("node_modules/")) continue;
    const name = path.replace(/^.*node_modules\//, "").replace("/", "%2f");
    const { dist } = await (await fetch(`https://registry.npmjs.org/${name}/${version}`)).json();
    n++; if (dist.attestations) prov++; if (dist.signatures) sig++;
  }
  console.log({ packages: n, withProvenance: prov, withSignatures: sig });
})()'
{ packages: 65, withProvenance: 2, withSignatures: 65 }

Only express itself and proxy-addr ship provenance. A team implementing PW.4.1 Example 3, "Obtain provenance information," would find it for 2 of 65 packages in one of npm's most common dependency trees.

An SBOM has the opposite limit: complete for what it sees, blind to what it does not. npm sbom --sbom-format cyclonedx lists every package in node_modules with a package URL such as pkg:npm/semver@7.7.2. It does not list tools your CI fetched with npx. During the axios compromise, CI jobs that ran CLIs through npx resolved the malicious version at execution time, outside any lockfile (our analysis of the blast radius has examples). An SBOM generated from that lockfile would be accurate and would not contain the package that ran.

What SSDF evidence said about the TanStack compromise

#

SSDF component evidence said the TanStack compromise was fine. On May 11, 2026, between 19:20 and 19:26 UTC, an attacker published 84 malicious versions across 42 @tanstack/* packages, according to the TanStack postmortem. The TanStack compromise was one wave of Mini Shai-Hulud, a worm that steals CI credentials and republishes itself.

No npm token was stolen. Attacker code got into the project's release workflow through a pull_request_target "Pwn Request" pattern and GitHub Actions cache poisoning, pulled an OIDC token out of runner memory, and published directly through the project's npm trusted publishing binding. The postmortem names the structural gap in one line: "OIDC trusted-publisher binding has no per-publish review." Our analysis found the implant also submits a Sigstore provenance attestation after publishing, so a malicious version can carry a valid provenance badge.

Here is each piece of component evidence the SSDF suggests, applied to a malicious version of @tanstack/react-router, which had over 12 million weekly downloads at the time:

SSDF task and exampleEvidence a consumer collectsWhat it said about the malicious version
PW.4.4 Ex. 6, PS.2.1: integrityRegistry signature, sha512 integrity hash in the lockfileValid. The registry signs whatever an authorized publisher uploads.
PW.4.1 Ex. 3, PS.3.2: provenanceSigstore provenance attestationCan be valid. The worm attests from inside the CI identity it hijacked.
PW.4.4 Ex. 1: known vulnerabilitiesCVE and advisory scanClean at publish time. No advisory existed yet.
RV.1.1 Ex. 1: monitor vulnerability databasesNVD, GHSA, and OSV feedsSilent until after the fact.
PS.3.2 Ex. 1: SBOMCycloneDX or SPDX component listAccurate, listing the malicious version by name and version.
NoneAnalysis of the package contentsMalicious: a new 2.3 MB obfuscated router_init.js that harvests CI secrets, plus an optionalDependencies entry pointing at an orphan Git commit with a prepare hook.

Only the last row caught the attack, and no SSDF task asks for it explicitly. Socket AI Scanner, which analyzes what a package's code does rather than what its metadata claims, flagged all 84 TanStack artifacts within six minutes of publication. That detection fits PW.4.4 as written; the SSDF just never says it is needed.

The SSDF is not useless here. Read from TanStack's side as a producer, the root causes map cleanly to SSDF tasks. PO.5.1 says to separate and protect each environment, yet attacker code running in the release workflow's test and cleanup steps could mint a publish token from the workflow's id-token: write permission. PO.3.2 says to operate toolchains securely, and TanStack's fixes, pinning third-party actions and adding repository-owner guards, are PO.3.2 work. The SSDF describes the producer's failure precisely. The consumer just cannot verify a producer's SSDF conformance from the artifact it downloads.

Is SSDF attestation still required?

#

SSDF attestation is no longer required governmentwide as of October 2026. On January 23, 2026, OMB memo M-26-05 rescinded the attestation mandates in M-22-18 and M-23-16. Agencies may still demand the attestation form, an SBOM, or both when their own risk assessment supports it.

M-22-18, issued September 14, 2022, required agencies to collect attestations from software producers. M-23-16, issued June 9, 2023, set collection deadlines: three months after the form's approval for critical software and six months for all other software. CISA released the final Common Form in March 2024. The form had four attestations, each mapped to SSDF tasks:

AttestationWhat the producer attestsSSDF tasks it maps to
1Software is developed and built in secure environments: separation, logged trust relationships, MFA, minimized risky software, encrypted credentials, monitoringPO.3.2, PO.3.3, PO.5.1, PO.5.2
2Good-faith effort to maintain trusted source code supply chains, using automated tools or comparable processes for internal code and third-party componentsPO.1.1, PO.3.1, PO.3.2, PO.5.1, PO.5.2, PS.1.1, PS.2.1, PS.3.1, PW.4.1, PW.4.4, PW.7.1, PW.8.1, RV.1.1
3Provenance maintained for internal code and third-party components "to the greatest extent feasible"PO.1.3, PO.3.2, PO.5.1, PO.5.2, PS.3.1, PS.3.2, PW.4.1, PW.4.4, RV.1.1, RV.1.2
4Automated vulnerability checks before releases, a pre-release vulnerability policy, and a vulnerability disclosure programPO.4.1, PO.4.2, PS.1.1, PW.2.1, PW.4.4, PW.5.1, PW.6.1, PW.6.2, PW.7.1, PW.7.2, PW.8.2, PW.9.1, PW.9.2, RV.1.1, RV.1.2, RV.1.3, RV.2.1, RV.2.2, RV.3.3

The producer's CEO, or a designee able to bind the company, signed it. CISA estimated the burden at 3 hours and 20 minutes per response. Critics of the rescission cited that estimate to argue the form was cheap. OMB Director Russell Vought's memo called the regime "unproven and burdensome software accounting processes that prioritized compliance over genuine security investments."

The policy changed twice before the rescission. Executive Order 14144, signed January 16, 2025, would have required machine-readable attestations, supporting evidence, and CISA validation. Executive Order 14306, signed June 6, 2025, removed those requirements and ordered NIST to update the SSDF instead.

The timeline in text form: NIST released the SSDF white paper in April 2020. EO 14028 followed on May 12, 2021, and SP 800-218 version 1.1 on February 3, 2022. M-22-18 required attestations on September 14, 2022, and M-23-16 set deadlines on June 9, 2023. The Common Form was released in March 2024, and SP 800-218A in July 2024. EO 14144 tightened attestation on January 16, 2025, and EO 14306 reversed that on June 6, 2025. The SSDF 1.2 draft appeared on December 17, 2025. M-26-05 rescinded the mandate on January 23, 2026, and comments on the 1.2 draft closed on January 30, 2026. EO 14306's deadline for a final SSDF 1.2 passed on April 16, 2026. As of October 18, 2026, SSDF 1.2 is still a draft.

Our view: losing the mandate costs less than it looks, because the mandate never checked artifacts. A signed attestation to PW.4.4 is a statement about process. As TanStack showed, a producer can run that process honestly and still ship a dependency that steals its customers' CI secrets. The useful parts of the SSDF were always the tasks themselves, and those still stand.

SSDF 1.2: what the draft adds

#

The SSDF 1.2 draft, published as SP 800-218 Revision 1 on December 17, 2025, adds two practices and expands implementation examples. EO 14306 required a final version within 120 days of the preliminary update. That deadline fell on April 16, 2026, and NIST had not published a final version as of October 18, 2026.

  • PO.6, Define and Implement a Continuous Process Improvement Plan. Three tasks: update development environments as threats and tools change (PO.6.1), adopt processes and tools that avoid software errors (PO.6.2), and improve vulnerability response while periodically reviewing past decisions (PO.6.3).
  • PS.4, Ensure Software Updates Are Robust and Reliable. Four tasks: test every release, use tiered rollouts such as canaries and staged releases, include rollback mechanisms, and maintain reliable update infrastructure.

The draft's first PO.6.1 example matters most for dependencies. It suggests adding or updating scanning tools "to check for malicious content" in artifacts received from suppliers. That is the first time the SSDF's examples point at malicious third-party code rather than vulnerable code. In SSDF 1.1's practice table, the only mention of malicious content is PW.7.2's suggestion to have expert reviewers check your own code for backdoors.

The labels may still move. A May 20, 2026 NIST presentation on the revision lists the update practice as PW.10 rather than PS.4, and describes new AI considerations for AI-generated code and AI agents in the build pipeline. Neither change appears in the December draft. Cite task IDs from 1.2 only after NIST publishes the final.

SSDF vs. SLSA vs. OWASP SAMM

#

The SSDF, SLSA, and OWASP SAMM get compared constantly, but they answer different questions.

NIST SSDFSLSAOWASP SAMM
Question it answersWhich secure development outcomes should exist?Can a consumer verify how an artifact was built?How mature is our security program, and what comes next?
Unit42 tasks in four practice groups (v1.1)Levels within Build and Source tracks (v1.2)15 security practices in 5 business functions
EvidenceSelf-attestation, internal documentationSigned provenance a machine can verifyScored maturity assessment
ScopeWhole lifecycle, including vulnerability responseBuild and source integrity onlyWhole program, including governance
Checks what a dependency does?NoNoNo

Verdict: use the SSDF as the contract vocabulary with buyers and auditors. Use SLSA to produce the PS.2 and PS.3 evidence the SSDF asks for in a form machines can verify. Use SAMM to decide what to improve next. None of the three tells you whether the next version of a dependency is malicious, so pair them with analysis of package contents at install time.

Where the SSDF should go next

#

Respond to Vulnerabilities is the SSDF group most exposed to a failing data pipeline. RV.1.1 tells producers to monitor vulnerability databases, and in April 2026 NIST stopped enriching most CVEs in the NVD. The NVD now enriches only CVEs in CISA's Known Exploited Vulnerabilities catalog, software used by the federal government, or EO 14028 critical software. NIST attributed the change to a 263% increase in CVE submissions between 2020 and 2025. An RV.1.1 process that reads only the NVD now sees severity scores and product mappings for a shrinking slice of CVEs.

RV.2.1 asks you to analyze each vulnerability enough to understand its risk. Severity scores alone do not do that. Reachability analysis, which checks whether your code can actually call the vulnerable function, does. A VEX document records the result in a form a buyer can consume. Socket's OpenVEX export marks unreachable vulnerable code not_affected and reachable code affected. That is the kind of artifact RV.2 should ask for by name.

The larger gap is PW.4.4. The SSDF should promote the 1.2 draft's malicious-content example into a task. Every new third-party version should be checked for behavior: install scripts, obfuscated code, network and credential access, and new dependencies resolving to unexpected sources. Run that check before the code executes, because install time is where most malicious package payloads fire. The SSDF asks producers to prove their own process. The riskiest code in most releases was written by someone outside it.