Back to glossary

Software Development Lifecycle (SDLC)

The SDLC is the sequence of phases, from planning to maintenance, that a team uses to build, ship, and change software, with a review gate after each.

Also known as software development life cycle, software lifecycle, SDLC phases, SDLC models

The software development lifecycle (SDLC), also written software development life cycle, is the sequence of phases a team uses to take software from idea to retirement: planning, requirements, design, implementation, testing, deployment, and maintenance. Each phase produces an artifact and ends at a gate that decides what moves forward. Those gates decide which code gets reviewed before it runs.

The most important fact about the SDLC today is that most of the code it ships never passes through it the way the model assumes. The SDLC assumes code enters during implementation, written by your team, and gets checked during testing. Third-party dependencies enter at every phase instead, and they often execute before any gate sees them. When we added Express 5.3.0 to an empty project on November 4, 2026, npm installed 65 packages whose maintainer lists include 85 different npm accounts. Our position: an SDLC that only governs first-party code does not govern most of what ships. Every point where a dependency is resolved, installed, or updated is a phase boundary, and each one needs its own gate.

What is the SDLC?

#

The SDLC is a model of the work between deciding to build software and switching it off. It names the phases, the artifact each phase hands to the next, and the checkpoint where someone decides the artifact is good enough. Teams adopted it because the cost of a mistake grows with every phase it survives. A wrong requirement caught in planning costs a conversation. The same mistake caught after release costs a rewrite, a migration, and an apology.

The sequential model most people picture comes from a 1970 paper by Winston Royce, "Managing the Development of Large Software Systems," presented at IEEE WESCON in August 1970. Royce drew requirements, analysis, design, coding, testing, and operations as a one-way sequence, then rejected it as drawn. "I believe in this concept, but the implementation described above is risky and invites failure," he wrote. His objection was that testing comes last, so problems surface only after every design decision is already built. The word "waterfall" never appears in the paper. The industry named the diagram he warned against and adopted it anyway.

The formal reference today is ISO/IEC/IEEE 12207:2017, the international standard for software life cycle processes. Its table of contents lists 30 processes in four groups. Two of those 30 are agreement processes: acquisition and supply. The standard treats obtaining software from a supplier as a process of its own, separate from building it. That idea matters later in this article, because nobody runs an acquisition process for npm install.

A secure SDLC adds security activities to each phase, such as threat modeling during design and static analysis during implementation. We cover that variant on its own page, the secure software development lifecycle (SSDLC), and the main U.S. reference for it is the NIST Secure Software Development Framework.

What are the phases of the SDLC?

#

The SDLC is usually drawn as seven phases, though some sources merge planning with requirements or testing with implementation. The names vary more than the substance. Each phase answers one question and produces one artifact the next phase depends on.

PhaseQuestion it answersArtifact it producesTypical gate
PlanningShould we build this, at what cost and by when?Scope, estimates, project charterGo or no-go decision
RequirementsWhat must the software do?Requirements spec or user storiesStakeholder sign-off
DesignHow will it be built?Architecture, interfaces, technology and library choicesDesign review
ImplementationWrite itSource code and commitsCode review on a pull request
TestingDoes it meet the requirements?Test results and defect reportsPassing test suite, QA sign-off
DeploymentIs it running for users?Release artifact and deployed environmentRelease approval
MaintenanceIs it still correct, secure, and supported?Patches, updates, end-of-life planThe same gates, re-run for each change

Two things about this table are easy to miss. First, every gate reviews an artifact your team produced: a document, a design, a diff, a test report. Second, the only phase that is supposed to introduce new code is implementation, and the only phase that is supposed to judge code is testing. Both assumptions break as soon as the code was written by someone else.

SDLC models: waterfall, V-model, iterative, agile, and DevOps

#

An SDLC model is a rule for ordering and repeating the phases. The phases stay the same. What changes is how many times you go around, how big each pass is, and how fast feedback from testing and operations returns to design.

The models arrived as answers to the problem Royce described. Barry Boehm's spiral model, published in IEEE Computer in May 1988, repeats the phases in loops sized by the biggest open risk. The Agile Manifesto, written by 17 developers at Snowbird, Utah, on February 11 to 13, 2001, made short cycles with working software the default. DevOps then automated the cycle into a pipeline that runs on every commit.

ModelHow the phases runWhen feedback arrivesBest fitBreaks when
WaterfallOnce, in sequenceAt the end, in testingRequirements fixed by contract or regulationRequirements change mid-project
V-modelIn sequence, each design level paired with a test levelPer level, but still lateSafety-critical systems that need traceabilitySame as waterfall, and change is expensive
Iterative or spiralRepeated loops, each sized by the biggest open riskAfter each loop or prototypeLarge systems built on unproven technologyLoops never close, and the project drifts
Agile (Scrum, Kanban)All phases in short cycles of a month or lessEvery cycle, from usersProducts whose requirements evolveNo real user feedback, or long-range architecture is ignored
DevOps and continuous deliveryEvery commit runs through an automated pipelineMinutes, from tests and production telemetryServices shipped daily or fasterGates become automated checks that only see what they test

Our verdict: use a sequential model (waterfall or V-model) only when requirements are fixed by contract or regulation and a late change is more expensive than slow delivery, as with flight software or medical devices. Use iterative or spiral when the biggest risk is technical and you need prototypes to retire it. For almost everything else, use agile delivery on a DevOps pipeline. The trade is that DevOps compresses the gates into automated checks that run in minutes, which is fast enough to ship daily and too fast for anyone to read what a dependency update actually changed.

That compression is where the SDLC and the software supply chain meet. In a continuous delivery pipeline, design, implementation, build, test, and deploy can all happen within an hour of a commit. Every one of those stages can resolve and run third-party code.

Where do third-party dependencies enter the SDLC?

#

Third-party dependencies enter the SDLC at every phase, not only during implementation. A dependency is code your team did not write, chosen by name and version range, fetched from a registry, and executed with your credentials. The figure below marks where that happens in a typical JavaScript project, and where the usual gates sit.

PhaseHow third-party code entersGate that reviews the workDoes the code run before the gate?
PlanningIt does notGo or no-go decisionNot applicable
RequirementsIt does notStakeholder sign-offNot applicable
DesignA library is chosen by name, by a developer or an AI agentDesign review, which sees the name, not the codeNo code runs yet, but the choice is made
Implementationnpm install resolves and writes the full tree, 65 packages for ExpressCode review, which sees one line of package.jsonYes
Build (CI)Fresh runners install from scratch, and npx tools resolve outside the lockfileCI checksYes
TestingTest tools install their own dependenciesTest suite, which checks requirements and not intentYes
DeploymentRelease and signing jobs fetch tools at run timeRelease approval, which sees the build and not what it fetchedYes
MaintenanceVersion ranges and update bots change resolved versions continuouslyNone, unless an update pull request existsYes, with no gate at all for range drift

The developer laptop is the earliest and least watched entry point. Running npm install resolves the full dependency tree, including every transitive dependency your direct dependency declares, and writes it to disk before anyone reviews a diff. Until July 2026, npm also ran each package's install scripts by default at that moment. npm v12, released on July 8, 2026, turned preinstall, install, and postinstall scripts off by default. pnpm made the same change in version 10.0.0 in January 2025. Default-on install scripts were a design mistake, and both changes correct it. Older npm releases still run them, and as of November 2026 the Node 22 machine we tested on came with npm 10.9.9.

Here is what one implementation-phase decision pulls in. We ran this on November 4, 2026, with npm 12.2.1 and Node 22:

Bash
$ mkdir app && cd app && npm init -y > /dev/null
$ npm --version
12.2.1
$ npm install express
added 65 packages, and audited 66 packages in 1s

30 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
$ grep -A2 '"dependencies"' package.json
  "dependencies": {
    "express": "^5.3.0"
  }

# Count the npm accounts that can publish any package in the tree
$ jq -r '.packages | to_entries[] | select(.key != "")
    | "\(.key | sub(".*node_modules/"; ""))@\(.value.version)"' package-lock.json \
  | xargs -I{} npm view {} maintainers --json \
  | jq -r '.[] | if type == "string" then split(" ")[0] else .name end' \
  | sort -u | wc -l
85

One line in package.json produced 65 packages. Counting the maintainers field of each resolved version on the npm registry, 85 distinct npm accounts can publish a new version of at least one of them, and 17 distinct publisher identities, one of them GitHub Actions trusted publishing, uploaded the exact versions we got. Every one of those accounts is now part of your implementation phase. None of them appear in your code review.

Why does the SDLC miss dependency risk?

#

The SDLC misses dependency risk because its gates review changes to your repository, and dependency resolution changes the code you run without changing your repository. Three assumptions in the model break.

Code enters through commits

#

The first broken assumption is that new code arrives as a commit. A lockfile records an exact tree, but only for the tree that was already resolved. Most dependency declarations are ranges: in the Express tree above, 122 of the 125 dependency edges in package-lock.json use a range rather than an exact version. Pinning your own direct dependency exactly does not pin what it depends on. Two installs of the same manifest, two weeks apart, produce different code:

Bash
# Two empty directories, the same package.json, express pinned exactly
$ cat package.json
{"name":"app","version":"1.0.0","dependencies":{"express":"5.3.0"}}

$ npm install --before=2026-10-20T00:00:00Z   # directory a: the registry as of Oct 20
$ npm install                                  # directory b: the registry on Nov 4

# Resolved versions that differ between the two package-lock.json files
body-parser   2.3.0   ->  2.4.0
encodeurl     2.0.0   ->  2.0.1
on-finished   2.4.1   ->  2.4.2
qs            6.16.1  ->  6.17.1

Four packages changed with no commit, no pull request, and no review. Nothing here is malicious. The same mechanism is what made the Axios compromise spread. On March 31, 2026, an attacker published axios@1.14.1 and axios@0.30.4. The only meaningful change was a new dependency, plain-crypto-js@4.2.1, which installed a remote access trojan. Any fresh install that matched a caret range like ^1.14.0 resolved to the malicious version without a change to the consuming project. The timeline below is reconstructed from npm registry timestamps and Socket's reporting.

Time (UTC)OffsetEvent
Mar 30, 05:57T-18hplain-crypto-js@4.2.0 published, a clean copy of crypto-js with no payload
Mar 30, 23:59T+0plain-crypto-js@4.2.1 published with the remote access trojan installer
Mar 31, 00:05T+6mSocket flags plain-crypto-js@4.2.1 as malicious
Mar 31, 00:21T+23maxios@1.14.1 published with plain-crypto-js as a dependency; fresh installs matching ^1.14.0 resolve it
Mar 31, 01:00T+62maxios@0.30.4 published on the 0.x line
Mar 31, 03:25T+3h26mnpm replaces plain-crypto-js with a security placeholder
Mar 31, 23:59T+24hThe first moment a 24-hour cooldown, such as pnpm 11's default, would allow plain-crypto-js@4.2.1; it was already gone

The exposure did not stop at projects that listed Axios. In the Axios compromise's hidden blast radius, we observed a CI pipeline that ran a CLI through npx and pulled the malicious dependency through a transitive Axios range, with no project lockfile involved. As that post puts it, "Lockfiles make existing installs deterministic. They do not make new installs safe."

Testing finds defects

#

The second broken assumption is that the testing phase catches bad code. Tests verify that software does what its requirements say. A malicious dependency that reads environment variables and posts them to a remote server does not break any requirement, so every test passes. Vulnerability scanning in the testing phase has the same blind spot from a different direction: it matches packages against known CVEs, and malware does not get a CVE. Our Express install above reported "found 0 vulnerabilities," which is true and says nothing about what the code does. Analyzing what is actually in the package, rather than what its metadata and advisories claim, is the only test that applies.

The supplier is accountable

#

The third broken assumption is that third-party code went through someone else's equivalent of your SDLC. Every dependency does have its own lifecycle, run by its maintainer, and your SDLC inherits its weakest gate. In the Axios case the weak point was the maintainer's own machine. The maintainer confirmed a targeted social engineering attack, and said he believes the attacker hijacked his active npm and GitHub sessions. An attacker holding the maintainer's own sessions is not stopped by 2FA or OIDC-based publishing. Provenance and signatures are necessary, but they cannot tell you that a legitimate account was being driven by someone else.

The release phase is exposed the same way. OpenAI disclosed that the malicious Axios version ran in its macOS app-signing workflow on March 31, 2026, in a GitHub Actions job with access to code signing certificates. OpenAI attributed it to a floating tag instead of a commit hash and no minimum release age for new packages. It rotated the certificate and required users to update. The signing step is the last gate in most SDLC diagrams, and third-party code ran inside it.

Putting gates where dependencies enter

#

A dependency gate belongs at the moment of resolution or installation, not at the next code review. Each control below covers one entry point and has a cost.

Entry pointControlWhat it costsWhat it misses
npm install on a laptopInstall scripts off by default (npm 12, pnpm 10 and later)Packages with native builds need explicit approvalMalicious code that runs on import, and scripts you already approved
CI buildCommitted lockfile plus npm ci or pnpm install --frozen-lockfileEvery update needs a deliberate lockfile changeNew dependencies, npx, global installs, and tools outside the project
Any fresh resolutionCooldown: a release-age setting in npm, pnpm, Yarn, or BunSecurity patches wait the same windowMalicious versions older than the window, and anyone can set it to zero
Any download from a registryPackage firewall: a proxy that checks each package requestA proxy every installing machine must route throughMalicious packages that have no verdict yet
Pull requestDependency-aware review of manifest and lockfile changesReview time on every version bumpAnything resolved outside a pull request
Maintenance triageReachability analysis of known CVEsCall-graph analysis per languageMalware, which has no CVE to triage

Two of these involve Socket, so to be specific about what they do. Socket Firewall runs as an HTTP and HTTPS proxy between the package manager and the registry and blocks known malicious packages at any depth before they are downloaded. It is free in wrapper mode, as in sfw npm install, and it covers installs that never touch a pull request, such as a laptop or an npx call in CI. It blocks only what already has a malicious verdict. Socket for GitHub watches pull requests that change manifests and lockfiles, analyzes each added package, and comments when it finds signals such as a new install script. It sees only dependency changes that arrive as a pull request.

The cooldown deserves a warning label. A dependency cooldown refuses versions younger than a set age. npm added a minimumReleaseAge setting in its 11.x releases, and pnpm 11 made 24 hours the default in April 2026. A 24-hour cooldown would have kept the malicious dependency out, because npm replaced plain-crypto-js with a security placeholder about three and a half hours after the malicious version was published. It also delays every security patch by the same window, and anyone can set it to zero in configuration.

Update bots move the maintenance phase onto a schedule. Automated dependency updates are good for patch latency and dangerous when merged without review, because the pull request diff shows a version number, not the code that changed. A package firewall at install time, or a dependency-aware review on those pull requests, is what turns a version bump back into something a human or a tool actually inspected.

The phase the diagrams leave out

#

ISO 12207 models acquisition as an agreement process between an acquirer and a supplier. Open source acquisition happens on every install, in every phase, many times a day, and nobody accepts anything. We think the SDLC should draw dependency ingestion as its own recurring phase, owned by someone, with a gate wherever resolution happens.

The open problem is that resolution is leaving the places we know how to gate. AI coding agents now pick packages during design and install them during implementation, often in a sandbox that never produces a commit. As Socket strategic advisor Brad Arkin wrote in June 2026, "Code now enters in more places than the org chart admits." An SDLC that only reviews what reaches the repository is reviewing a shrinking fraction of the code that runs.