Back to glossary

Secure Software Development Lifecycle (SSDLC)

A secure SDLC adds a security activity and an enforced gate to every phase of software development, from requirements through vulnerability response.

Also known as Secure SDLC, Secure Development Lifecycle, Secure Software Development Life Cycle, Microsoft SDL

A secure software development lifecycle (secure SDLC, or SSDLC) is a software development lifecycle in which every phase has a defined security activity and an enforceable gate: security requirements, threat modeling, secure coding and review, security testing, a release review, and vulnerability response. Each gate inspects only the artifacts that pass through it, which decides what the process can catch.

The gates are the part that matters in 2026. The frameworks behind the secure SDLC were designed around code your own team writes. Microsoft's founding description of its Security Development Lifecycle, published by Steve Lipner and Michael Howard in March 2005, defines six phases and never addresses third-party components. As of November 2026, "Secure the software supply chain" is one of the 10 practices in Microsoft's current SDL. The process grew a supply chain practice, but most secure SDLC gates still inspect only first-party artifacts: a design document, a pull request diff, a test report, a release questionnaire.

Our position: a secure SDLC needs a gate at dependency intake, enforced by the package manager and backed by analysis of what each package actually does, because none of the classic gates inspects code that arrives through dependency resolution. We also think the most common argument for a secure SDLC, that a bug costs 100 times more to fix in production, should be retired. Its source is a set of 1981 IBM training course notes. A gate belongs where its check can see the thing being checked, before that thing runs.

What is a secure SDLC?

#

A secure SDLC is the ordinary software development lifecycle with security work assigned to every phase and a checkpoint that can stop work from moving forward. The phases stay the same. What changes is that each phase now produces a security artifact alongside its normal output: a list of security requirements, a threat model, a scan report, a release sign-off.

The practice goes by several names. Microsoft calls its version the Security Development Lifecycle (SDL). The BSIMM survey calls the per-phase activities "SSDL touchpoints." "Secure development lifecycle," "secure SDLC," and "SSDLC" all describe the same idea, and this page uses secure SDLC throughout.

The secure SDLC became an engineering discipline at Microsoft. On January 15, 2002, Bill Gates sent the company his Trustworthy Computing memo, reprinted in full by The Register: "when we face a choice between adding features and resolving security issues, we need to choose security." Microsoft ran a "security push" during the verification phase of Windows Server 2003 in early 2002. Lipner and Howard's paper then formalized the result into six phases: requirements, design, implementation, verification, release, and support and servicing.

The release phase ended in a Final Security Review, run by a central security team two to six months before ship. The paper reduces it to one question: "From a security viewpoint, is this software ready to deliver to customers?" That question is still the right one. The answer now depends on code the product team never wrote and the review never saw.

A secure SDLC is a process model, which makes it different from two terms it is often confused with. The NIST SSDF is a catalog of outcomes that a secure SDLC should produce, with no opinion about phases. DevSecOps is a delivery style that turns secure SDLC gates into automated pipeline jobs. A team can run a secure SDLC without DevSecOps, but DevSecOps without a secure SDLC behind it is a set of scanners with no agreed definition of done.

What each secure SDLC gate inspects

#

Every secure SDLC gate inspects an artifact, and every artifact on the left side of the figure below was produced by your team. Dependency code takes a different route. It is chosen by name, resolved by a package manager, and executed on a laptop or CI runner, mostly in phases whose gates are looking at something else.

GATE ON YOUR CODEDEPENDENCY CODE1 · REQUIREMENTSSecurity requirementsinspects: requirements docRegistry allowlistonly if someone writes one2 · DESIGNThreat model reviewinspects: data flow diagramPackage picked by namein a spike, not by contents3 · IMPLEMENTATIONSAST + code reviewinspects: the PR diffnpm installfull tree resolved;PR shows lockfile lines4 · BUILDPipeline checksinspects: workflow configCI install, npx toolsinstall scripts execute here5 · VERIFICATIONDAST, fuzzing, pentestinspects: the running appSCA scanknown CVEs only;malware has none6 · RELEASEFinal security reviewinspects: a questionnaireShips as resolvedwhatever the build pulled in7 · RESPONSEVulnerability triageinspects: advisoriesUpdate bot PRdiff shows a version numberINTAKE GATE (PROPOSED)Solid boxes: gates that inspect an artifact your team wrote.Dashed boxes: dependency code passing through a phase unreviewed.Shaded boxes: where third-party code is fetched and first executes.

The figure pairs each of the seven phases with the gate that guards first-party code and with what happens to dependency code in the same phase. It marks the fetch and first execution of third-party code at implementation and build, and places a proposed intake gate between design and implementation, before the first install. The table carries the same information, and adds the security activity behind each gate.

PhaseSecurity activityGate inspectsDependency code in this phase
RequirementsSecurity and compliance requirements, abuse casesRequirements documentA registry allowlist or license policy, if anyone writes one
DesignThreat modeling, attack surface reviewData flow diagram and threat listPackages chosen by name and popularity in a spike, not by contents
ImplementationSecure coding standard, SAST, peer reviewThe pull request diffnpm install resolves and unpacks the full tree; the diff shows manifest and lockfile lines
BuildPinned toolchain, reproducible build, signingWorkflow config and build logsCI installs again and npx fetches tools; approved install scripts, or all of them on older npm, execute here
VerificationDAST, fuzzing, penetration testing, SCAScan reports and the running appSCA matches package versions against known advisories only
ReleaseFinal security review, provenanceA questionnaire and a sign-offWhatever the build resolved ships unread
ResponseVulnerability intake, patching, root cause analysisAdvisories and incident reportsUpdate bots open version bumps whose diff is a version number

Threat modeling during design is the one gate that can reason about dependencies at all, because a good threat model draws the package manager as a trust boundary. It still produces a diagram, not a verdict on the package that installs next Tuesday.

Why do secure SDLC gates miss dependency code?

#

Secure SDLC gates miss dependency code because each gate reviews a change your team made, and dependency resolution changes the code you run without anyone making a change. Walk the gates in order and each one has a specific blind spot.

Static application security testing (SAST) scans the repository, and node_modules is not in the repository. Code review sees a pull request in which a range like "axios": "^1.14.0" has not changed at all. Vulnerability scanning matches versions against advisories, and malware does not get a CVE. The Final Security Review asks the product team about its own software. None of these gates is broken. They were built to inspect a different thing.

The Axios compromise shows the failure end to end. On March 31, 2026, an attacker published axios@1.14.1 and axios@0.30.4 with one meaningful change: a new dependency, plain-crypto-js@4.2.1. Any project with a caret range such as ^1.14.0 resolved the malicious version on its next fresh install, with no commit and no pull request. The new dependency ran a 4,209-byte dropper, setup.js, from a postinstall hook. It downloaded a platform-specific remote access trojan, then deleted setup.js and swapped its own package.json for a clean copy with no postinstall script.

That cleanup step is the whole argument in one artifact. After the install finished, node_modules/plain-crypto-js looked like an ordinary copy of crypto-js. A SAST run, an audit of node_modules, or a release review that happened after install would have inspected a scrubbed crime scene. Install time is where most supply chain attacks execute, so the only gate that can stop one sits before the install. Socket's malware detection flagged plain-crypto-js@4.2.1 at 00:05:41 UTC, about six minutes after it was published, which is useful only to a gate that consults it before the package runs.

We cover where dependencies enter each phase, and why the SDLC model assumes they do not, in detail on our SDLC page. The point for a secure SDLC is narrower: adding security activities to phases does not help if the code never passes through the phase.

Where does the "100x cheaper to fix early" claim come from?

#

The "100x cheaper to fix early" claim comes from IBM training course notes, not a published study. Nearly every secure SDLC explainer repeats some version of it, usually citing the "IBM Systems Sciences Institute." The previous version of this page claimed fixes cost 6 times less in development than in testing and up to 100 times less than in production.

Laurent Bossavit traced the citation chain in a public investigation of the figures. Roger Pressman's textbook Software Engineering: A Practitioner's Approach printed the relative costs and cited "[IBM81]." That reference expands to "Implementing Software Inspections," course notes from the IBM Systems Sciences Institute, 1981. Bossavit describes the institute as an IBM training program, and found no published dataset behind the ratios. Later papers cited Pressman, and the ratios hardened into fact.

When researchers measured the effect directly, it was not there. Tim Menzies, William Nichols, Forrest Shull, and Lucas Layman examined 171 software projects run between 2006 and 2014. Their abstract is blunt: "We found no evidence for the delayed issue effect." Issues fixed in later phases did not consistently take more effort than issues fixed soon after they were introduced.

The secure SDLC does not need the myth, because a better reason for early gates exists. A check is only useful at a point where its subject exists and has not yet acted. Threat modeling works in design because the design is cheap to change while it is still a diagram. Code review works on a pull request because the diff exists and has not merged. An install script runs once, at install. A gate placed after install is not a more expensive version of a gate before install. It is a different control that cannot prevent the event. The placement rule we use is the earliest point where the subject exists, and always before it executes.

How do you implement a secure SDLC?

#

You implement a secure SDLC by turning each phase's security activity into a gate that fails closed, then adding the gate the classic models leave out: dependency intake. The order matters less than the enforcement. A secure SDLC that lives in a policy document and warns in CI is a reporting system.

Make gates fail the build

#

OWASP SAMM's highest maturity level for the build process says it directly: "Define mandatory security checks in the build process and ensure that building non-compliant artifacts fails." Start with the checks whose failures you will actually act on, and make them blocking. The cost is merges stopped by false positives. Plan an exception path with an owner and an expiry date before turning blocking on, or developers will route around the gate.

Threat model the package manager, not only the product

#

Every feature-level threat model should include the dependency install path: the registry, the maintainer accounts that can publish to it, and the install step that runs third-party code with your credentials. The cost is time per design review. The limit is that threat modeling names the risk but never inspects a package.

Gate dependency intake at install

#

The highest-leverage secure SDLC gate is the package manager configuration, because it runs on every install, in every phase, on laptops and CI alike. npm v12, released July 8, 2026, turned dependency install scripts off by default, 18 months after pnpm 10 blocked lifecycle scripts by default in January 2025. Default-on install scripts were a design mistake, and both changes correct it. The npm default is a soft skip with a warning. For a secure SDLC gate, turn the skip into a failure:

TOML, also INI
strict-allow-scripts=true
min-release-age=1

We ran this on November 8, 2026, with npm 12.2.2, in an empty project. Adding a package with an unapproved postinstall script fails the install:

Shell Session
$ npm install esbuild@0.25.0
npm error code ESTRICTALLOWSCRIPTS
npm error --strict-allow-scripts: 1 package(s) have install scripts not covered by allowScripts:
npm error   esbuild@0.25.0 (postinstall: node install.js)
npm error Approve them with `npm install-scripts approve`, deny them with `npm install-scripts deny`, or bypass this check with `--dangerously-allow-all-scripts`.

Approval is an explicit, reviewable change to package.json, and npm pins it to the exact version by default:

Shell Session
$ npm install-scripts approve esbuild
Approved esbuild:
  added esbuild@0.25.0

$ grep -A2 allowScripts package.json
  "allowScripts": {
    "esbuild@0.25.0": true
  }

The pin is what makes the gate useful. When we then requested esbuild@0.25.1, npm failed again with the same ESTRICTALLOWSCRIPTS error, because the approval covered 0.25.0 only. A compromised new version of an approved package does not inherit the approval. plain-crypto-js, a brand-new dependency with a postinstall hook, would have failed this gate in CI before setup.js ran.

The second line sets a dependency cooldown: min-release-age=1 makes npm resolve only versions published more than one day earlier. npm 12 also refuses git and remote tarball dependencies by default; its config reports allow-git = "none" and allow-remote = "none".

Each control has a cost and a gap. Strict mode breaks native modules and binary downloaders until someone approves them, and approval fatigue turns review into a rubber stamp. A cooldown delays security patches by the same window it delays attacks. Most importantly, none of these settings inspect code that runs on import rather than at install. Older npm releases lack the settings entirely: the Node 22.23.4 runtime we tested came with npm 10.9.9.

Analyze what packages do, not what their metadata claims

#

The install gate controls when third-party code may run. It cannot tell you whether the code is malicious. SAMM's Software Dependencies stream reserves that for its top maturity level: "Analyze used dependencies for security issues in a comparable way to your own code." In practice, that means inspecting each new version for behavior such as network access, credential reads, obfuscated strings, and new install-time execution, before it reaches a machine with secrets.

One way to put that analysis at the intake gate is Socket Firewall. Socket Firewall Free wraps a package manager command, as in sfw npm install, and blocks network requests for package artifacts that Socket has confirmed as malware, at any depth in the tree. It blocks only confirmed malware, does not check artifacts already in the local cache, and works only with public registries.

Triage vulnerabilities by reachability

#

Software composition analysis in the verification phase produces a list of dependencies with known CVEs, and most of those alerts are noise. A vulnerable function your code never calls is not an emergency. Reachability analysis checks whether a call path exists from your code to the vulnerable code, and should drive triage instead of severity scores. Its limit is precision: dynamic dispatch, reflection, and code loaded at runtime can hide a real path.

Microsoft SDL vs OWASP SAMM vs BSIMM vs NIST SSDF

#

Microsoft SDL, OWASP SAMM, BSIMM, and the NIST SSDF are the four reference models most secure SDLC programs start from, and they answer different questions. Microsoft SDL tells you what one large vendor does. SAMM tells you what to improve next. BSIMM tells you what other firms actually do. The SSDF tells an auditor which outcomes to look for.

BSIMM deserves a closer look because it is the only descriptive model. BSIMM16, released in January 2026, observed 111 organizations and catalogs 128 activities in 12 practices across four domains. Its report states that the model's purpose is to "descriptively observe and quantify the actual activities" of real programs, not to prescribe them. The most common activity, creating or interfacing with incident response, appeared in 87.6% of firms. Activity SR1.5, "Identify open source," appeared in 72.7%, so assessors did not observe an open source inventory in more than a quarter of the programs surveyed.

ModelKindShapeWhat it says about third-party codeUse it to
Microsoft SDLPrescriptive, one vendor's program10 practices in the current versionThe 2005 paper says nothing; the current version lists "Secure the software supply chain" as a practiceCopy a working program's structure
OWASP SAMM 2.0Prescriptive maturity model5 business functions, 15 practices, 3 maturity levelsA Software Dependencies stream; analyzing dependencies like your own code is maturity level 3Plan the next improvement
BSIMM16Descriptive survey111 firms, 128 activities, 12 practices, 4 domainsSR1.5 "Identify open source" observed in 72.7% of firmsBenchmark against peers
NIST SSDF 1.1Outcome catalog19 practices, 42 tasks, 4 groupsTask PW.4.4: keep verifying that third-party components meet your requirementsSpeak to buyers and auditors

Our verdict: use SAMM to run the program, because it is the only one of the four built to sequence improvements. Use BSIMM once a year to check that sequence against what peers do. Map the result to NIST SP 800-218 when a customer or regulator asks. Read Microsoft's SDL for examples, not as a template, since it assumes Microsoft's scale. None of the four tells you whether the next version of a dependency is malicious, so each needs the intake gate above.

Level 3 should be level 1

#

The reference models treat deep analysis of dependency code as advanced maturity or leave it out. SAMM puts it at level 3. Microsoft's 2005 description of the SDL did not mention third-party components at all. In BSIMM16, assessors found no open source inventory in more than a quarter of firms. Yet one direct dependency routinely brings dozens of packages: adding Express 5.3.0 to an empty project installed 65 packages when we measured it on November 4, 2026. The install step is the first place any of that code executes.

We think the secure SDLC should be redrawn with dependency intake as a gated phase of its own, owned by a named team, enforced by the package manager, and backed by behavioral analysis that runs before install. The open problem is that installs are leaving the places where gates live. Brad Arkin, writing as a Socket advisor in The Code You Didn't Write Is Still Yours to Defend, described AI agents pulling packages into sandboxes that no scanner watches. His prescription is the right one for the secure SDLC too: "What works is governance at the point of ingest."