Secure SDLC • Deep Dive

Prove It, Then Ship It: A Secure Development Standard You Can Copy

A secure development standard comes down to three rules: every change proves it works, someone who didn’t write it approves it, and it can put itself back. Here is the full secure software development lifecycle (secure SDLC), stage by stage, mapped to NIST’s Secure Software Development Framework, OWASP and the CSSLP domains.

• 19 min read • Secure SDLC • NIST SSDF • Threat Vector Management

By Fezz · Threat Vector Management · October 2026

Research, fact-checking and graphics support by Claude (Anthropic)

: added OWASP (SAMM, ASVS, Top 10 CI/CD Security Risks), CSSLP and DevSecOps mappings.

BLUF

Bottom Line Up Front

How to read this. Each stage opens with its own bottom line (Do now / Skip if), then What, So what and Now what. Ridgeline is a hypothetical company; the at-a-glance table maps every stage to NIST SSDF, OWASP and the CSSLP domains.

To make the standard concrete, this post follows Ridgeline, a hypothetical 15-person company that builds a customer web portal, through each stage of building software. Ridgeline isn’t a real company or a client of ours. The standard is the one we recommend. It is DevSecOps in practice: the security gates live in the same pipeline that ships the code, so security keeps pace with development instead of waiting at the end.

At a glance: six stages, each with a gate

Every stage has a gate, and findings loop back to design1 Designthreat model every featuresecurity requirements written2 Buildfast checks on every changereal packages only3 Reviewapproved by a non-authorprotected release branch4 Verifyfull gate on the exact codetests proven able to fail5 Releasesigned, stamped, reversibleold release kept runnable6 Operatewatch, alert, respondoutside bug reports welcomefindings and incidents loop back to designUnderneath all six: every part stays current, and every fault heals itself on the next run.
The secure development lifecycle: six stages, each with a gate.

Each stage has a gate that has to pass before work moves on, and what is learned in production feeds the next design. The table lists every gate, the first thing to do about it, and where it maps in NIST SSDF, OWASP SAMM v2, the OWASP Top 10 CI/CD Security Risks and the CSSLP exam domains.

StageGate before work moves onDo nowNIST SSDFOWASP SAMM v2OWASP CI/CD riskCSSLP domain
1. DesignEvery feature answers the four threat-modeling questions; each risk becomes a written requirementAdd the four questions to the feature templatePO.1, PW.1Threat Assessment; Security RequirementsNo direct entry3 Requirements; 4 Architecture and Design
2. BuildFast checks pass on every change; new dependencies confirmed realRun unit and regression tests on every changePW.4, PW.5, PW.7Secure BuildCICD-SEC-3 Dependency Chain Abuse; CICD-SEC-6 Insufficient Credential Hygiene5 Implementation; 8 Supply Chain
3. ReviewSomeone who didn’t write the change approves it; checks are requiredProtect the release branchPS.1, PW.7No direct practiceCICD-SEC-1 Insufficient Flow Control Mechanisms2 Lifecycle Management
4. VerifyThe full gate passes on the exact code, and every check has proved it can failPlant a defect in each test harnessPW.8Requirements-driven Testing; Security TestingNo direct entry6 Testing
5. ReleaseSaved, signed and reversible; a failure undoes itself, then fixes itself within limitsBack up before every change and test a restorePS.2, PS.3Secure DeploymentCICD-SEC-9 Improper Artifact Integrity Validation7 Deployment, Operations, Maintenance
6. OperateWatched after release; silence alerts; outsiders can report bugsAlert when a job processes nothingRV.1, RV.2, RV.3Incident Management; Operational ManagementCICD-SEC-10 Insufficient Logging and Visibility7 Deployment, Operations, Maintenance

WHAT

The failure to design against

Ridgeline’s nightly import job stopped importing in week one of a quarter. It still exited cleanly, the dashboard stayed green, and nobody noticed for three weeks, until a customer asked why their numbers hadn’t moved.

That’s the most expensive kind of bug: one that breaks nothing loudly. An empty to-do list and a broken one look the same from the outside. Everything in this standard comes back to two rules.

NOW WHAT

1. Design: decide how it could be abused before building it

Bottom line

Do now: add the four threat-modeling questions to the feature template, and write each real risk down as a requirement.

Skip if: the change is cosmetic and touches no data, login, permission or outside input.

What

When Ridgeline plans a customer file-upload feature, the ticket doesn’t move to “ready” until it answers the four questions from the Threat Modeling Manifesto:

  1. What are we working on? A one-line data flow: who sends what, where it’s stored, who can read it.
  2. What can go wrong? Walk the flow with a simple checklist such as STRIDE: spoofing, tampering, repudiation, information disclosure, denial of service, elevation of privilege.
  3. What are we going to do about it? Each real risk becomes a written security requirement, for example “uploads are scanned, size-capped and stored outside the web root.”
  4. Did we do a good enough job? Each requirement becomes a test that the Verify stage runs.

So what

Tests prove the code does what the spec says. They can’t tell anyone the spec forgot how a feature could be misused. A risk named in design costs a sentence; the same risk found in production costs an incident.

Now what

The principle: a risk named in design costs a sentence. Maps to SSDF PO.1 (define security requirements for software development) and PW.1 (design software to meet security requirements and mitigate security risks). OWASP SAMM: Threat Assessment and Security Requirements. CSSLP: Domains 3 (Secure Software Requirements) and 4 (Secure Software Architecture and Design).

2. Build: fast checks on every change, and real packages only

Bottom line

Do now: run unit and regression tests on every change, and confirm every new dependency is a real, established package before adding it.

Skip if: no code is written in-house.

What

Rigor and speed only conflict when every check runs on every keystroke. Ridgeline’s developers make dozens of changes an hour, so they work in two tiers.

Iterate in seconds, ship only stamped codeMake a changedozens an hourFast check, every changeseconds, never skippedFull gate, per releasestamps the exact codeShiprefused without a valid stampfail: fix it, add a regression test, retryevery check passesAny edit after the stamp voids it, so the full gate runs again on the new code.
Two speeds: a fast check on every change, the full gate once per release.

AI writes the tests; it doesn’t grade them. Ridgeline uses an AI assistant to draft hundreds of tests from the spec in minutes, and people review whether they check the right things. Writing tests is now the cheap part. Keeping them honest is the expensive part, and that is what the Verify stage is for.

Secrets never live in code. Keys and passwords come from a secrets manager or the operating system’s keychain at run time. The secret scan is the backstop, not the plan.

So what

AI-written code adds a new risk: packages that don’t exist. In a study of 576,000 code samples from 16 code-generating models, about 19.7% of recommended packages were hallucinated (made up): on average, at least 5.2% for commercial models and 21.7% for open-source ones, across 205,474 unique made-up names (Spracklen et al., USENIX Security 2025; The New Stack). In repeat tests, 43% of the made-up names came back every time. That repeatability is what makes “slopsquatting” work: an attacker registers the made-up name and waits. OWASP files this family of attacks under CICD-SEC-3, Dependency Chain Abuse.

Now what

At Ridgeline, a new dependency is added only after a person confirms it exists in the official registry, has a real release history and a known publisher, and is the package they meant. A waiting period on new releases doesn’t cover a brand-new package name, so this check stands on its own.

The principle: be fast while building and strict before shipping. Maps to SSDF PW.4 (reuse existing, well-secured software when feasible instead of duplicating functionality), PW.5 (create source code by adhering to secure coding practices) and PW.7 (review and/or analyze human-readable code to identify vulnerabilities and verify compliance with security requirements). OWASP SAMM: Secure Build. CSSLP: Domains 5 (Secure Software Implementation) and 8 (Secure Software Supply Chain).

3. Review: someone who didn’t write it approves it

Bottom line

Do now: protect the release branch so nothing reaches it without a pull request approved by someone other than the author.

Skip if: never. A one-person team can use a separately run AI reviewer, with the person signing off on the risky changes named in design.

What

So what

When one developer and an AI assistant write both the code and the tests, the author is also the approver. That’s the gap an auditor finds first, and it’s cheap to close. OWASP ranks it first among CI/CD risks: CICD-SEC-1, Insufficient Flow Control Mechanisms.

Now what

Turn on branch protection with required reviews and required checks, then try to push straight to the release branch once to prove it’s refused.

The principle: the person who wrote the change shouldn’t be the only one who approved it. Maps to SSDF PS.1 (protect all forms of code from unauthorized access and tampering) and PW.7, and to the change-management criterion (CC8.1) in the AICPA Trust Services Criteria behind SOC 2. CSSLP: Domain 2 (Secure Software Lifecycle Management).

4. Verify: the release gate, and tests that can fail

Bottom line

Do now: plant a deliberately broken “canary” in each test harness, and fail the run when any canary isn’t caught.

Skip if: never. A check that has never caught anything hasn’t been tested.

What

Every check below has to pass on the exact code being released. A check that can’t run is marked INCOMPLETE, and INCOMPLETE blocks the release. A pass writes a stamp tied to a fingerprint of every file; the ship command refuses code without a matching stamp, and any later edit voids it.

CheckIn plain termsWhat it catchesNIST SSDF
Unit and regression testsTest each small piece, plus one test for every bug ever fixedA rule that quietly changed; an old bug coming backPW.8, RV.3
Design-requirement testsOne test for each security requirement written in design, drawn from OWASP ASVS where it fitsA risk named in design that the code doesn’t handlePW.1, PW.8
Integration and end-to-end testsTest the pieces together, and drive the app the way a user doesParts that no longer agree; a flow that brokePW.8
Mutation testingMake small deliberate changes to the code and confirm the tests failTests that run but don’t actually check anythingPW.8
Static analysis (SAST)Read the source for security flawsInjection, unsafe file paths, weak cryptoPW.7
Secret scanSearch the full git history for keys and passwordsA credential committed today or years agoPS.1, PW.7
Software composition analysis (SCA) with an SBOMList every package, container and tool shipped or built with, then check each for known flawsA vulnerable library several layers deepPW.4, RV.1
FuzzingFeed every parser of outside input huge numbers of malformed inputsCrashes, runaway regular expressions (ReDoS), slowdowns that grow with inputPW.8
Dynamic testing (DAST)Attack the running app from outsideLogin bypass, cross-site request forgery, Host-header and DNS-rebinding tricks, path traversal, missing headers, oversized requestsPW.8
Load and resiliencePush traffic and slow clients at itMissed response-time targets, errors, memory leaksPW.8
Real-browser and accessibility checksCheck the interface in an actual browserBroken layouts; screen-reader and keyboard failuresPW.8
License checksConfirm everything shipped may be shippedIncompatible licenses, copied codePW.4

So what

A suite that can’t fail is worse than none, because it gives false confidence. A security scanner that silently checks nothing is the most dangerous tool in the pipeline.

Now what

The principle: a release is a claim, and the gate is the evidence. Trust a check only after watching it catch something. Maps to SSDF PW.8 (test executable code to identify vulnerabilities and verify compliance with security requirements). OWASP SAMM: Requirements-driven Testing and Security Testing. CSSLP: Domain 6 (Secure Software Testing).

5. Release: signed, reversible, and able to fix itself

Bottom line

Do now: back up before every change, test a restore once, and make the deploy undo itself automatically when its checks fail.

Skip if: the app has no database and redeploys in seconds; the undo still applies, the backup step gets lighter.

What

At Ridgeline, the program itself saves what it needs, proves the change, undoes it on failure, and then works on a fix. Nobody has to follow a runbook at 2 a.m. The rule covers code deploys, configuration, database migrations, infrastructure, containers and any settings the program manages.

A failed change undoes itself, then tries to fix itself, within limits1 Baselinehealth check first;already broken = stop2 Savefiles, config, DB, release;hash-matched copy3 Change + provetests on the real result;health no worse4 Liveold release keptrunnable side by sideOne-click undo30 days; says whatreturns and is lostAuto-undoall or nothing, verified;old release keeps servingAgent fixes, retriesfix is a new change;may not touch the testsEscalate to a personloud alert with theevidence attachedStop, unchangedreport the brokenstarting pointfailsregret laterunhealthyfix re-enterstries or timer used upEvery undo, retry and fix is logged and reported; a healed failure is never reported as a pass.
Patch, prove, roll back, then fix within limits: a person is called only when the tries or the timer run out.
  1. Baseline first. Run health checks before touching anything. If the system is already broken, stop with nothing changed; a failure afterward would prove nothing.
  2. Save before changing. Save everything needed to put it back exactly: files, configuration, a database backup, the previous release, infrastructure state. Check free space first. Fingerprint (hash) the original and the copy, and keep the copy only if they match. Store it where the thing being changed can’t reach it.
  3. Prove the change. Each change carries its own proof that it did what it claimed, and health must not drop below the baseline.
  4. Undo automatically on failure. All or nothing, never half-restored. Verify the undo. The previous release keeps serving, so nothing is rushed.
  5. One-click undo for 30 days. Undo states exactly what it restores and what newer work would be lost, then asks to confirm. Nothing is deleted: expired restore points are archived.
  6. Keep the previous release runnable side by side (blue/green, versioned folders or feature flags). Every database schema migration is reversible and backed up first.
  7. Log every change in an append-only, hash-chained log, so a tampered restore point is caught and refused.
  8. Rehearse on the real target. Make a harmless, marked change, undo it, and prove it’s gone byte for byte before trusting the mechanism.

So what

An undo protects production, but the work still isn’t shipped, and an alert alone hands the job back to a person. The fix loop finishes the job without lowering the bar.

Now what: fix it, within limits

The principle: if it can’t be put back, it isn’t ready to change. Maps to SSDF PS.2 (provide a mechanism for verifying software release integrity) and PS.3 (archive and protect each software release), and to the change-management (CC8.1) and recovery (A1.2, A1.3) criteria behind SOC 2. OWASP SAMM: Secure Deployment. CSSLP: Domain 7 (Secure Software Deployment, Operations, Maintenance).

6. Operate: watch it, respond to it, and let outsiders report it

Bottom line

Do now: alert when a scheduled job runs and processes nothing, and publish a security.txt with a working contact.

Skip if: nothing is reachable from the internet and nothing runs on a schedule.

What

So what

A clean release is the start of the job, not the end. Some failures only show up under real traffic, days later. The silence rule alone would have caught Ridgeline’s three-week import failure on its first night.

Now what

Every incident and every reported bug ends with a root cause, a fix and a regression test, so it can’t quietly come back. What was learned goes back into the next design.

The principle: watch for the job that did nothing as closely as the job that crashed. Maps to SSDF RV.1 (identify and confirm vulnerabilities on an ongoing basis), RV.2 (assess, prioritize and remediate vulnerabilities) and RV.3 (analyze vulnerabilities to identify their root causes), and to OWASP CICD-SEC-10, Insufficient Logging and Visibility. OWASP SAMM: Incident Management and Operational Management. CSSLP: Domain 7.

Underneath every stage: self-healing

A fault should repair itself on the next run, with no one having to remember it happened. If the fix needs a person to run a cleanup command, it isn’t fixed.

What goes wrongWhat the system does on its own
A change is cut off by a crash, a sleeping laptop, a deploy or a timeoutThe next run finds the half-finished change and either completes it or undoes it.
A cache, saved session or staged file gets corruptedState is checked when it’s read, not only when it’s written, so bad entries from before a check existed are dropped and rebuilt.
The network is down, a file moved, a key is missingThe job reports what happened in plain words and never produces a wrong answer. A failed download retries on the next run without raising a false alarm.
Someone else edits the file mid-changeEdits target content (keys, names, patterns), not line numbers, and the version is checked before writing.
A restore point is altered outside the programThe hash-chained log catches it, and the restore point is refused.
A job hangs or loopsEvery job, scheduled or not, has a timeout. Long jobs can be resumed, are safe to re-run, and keep their partial progress.
A scheduled job keeps failingIt backs off on its own. A person who names the job can override the backoff; an unattended job never can.
A release fails its checksIt undoes itself, then the pipeline agent tries a fix as a new change through the full pipeline. After a capped number of tries or its time limit, a person gets the alert and the evidence.

Underneath every stage: keep every part current

Every piece Ridgeline runs updates on a schedule: dependencies, runtimes, base images, tools and operating-system packages. Each update goes through the same save, prove and undo cycle as a code change.

Maps to SSDF PW.4 and RV.1, OWASP SAMM Environment Management, and OWASP CICD-SEC-3 and CICD-SEC-8 (Ungoverned Usage of 3rd Party Services).

Copy this standard

Nobody needs all of it on day one. A few fundamentals, done right, do most of the work. Start with what stops silent failures and unreviewed changes, then add depth.

WhenWhat to put in placeSkip if
Now (first 30 days)Fail loudly: no job reports success on a path that did nothing, and every job has a timeout. Alert when a job processes nothing.Never.
NowBack up before every change, and test a restore once. A backup that has never been restored is a hope, not a backup.Never.
NowProtect the release branch and require approval from someone other than the author.Never.
NowScan the full git history for secrets, rotate anything found, and move secrets into a secrets manager.Never.
NowRun unit and regression tests on every change; every bug fix adds a regression test.No code is written in-house.
Fast follow (30–90 days)Plant a defect in each test harness and fail the run if it isn’t caught.Never.
Fast followKeep an SBOM, check it for known flaws on every change, and confirm every new dependency is real before adding it.There are no third-party dependencies (rare).
Fast followPublish security.txt and a short disclosure policy; write a one-page incident playbook.Nothing is reachable from the internet.
Fast followMake deploys reversible: keep the previous release runnable and every migration reversible.The app has no database and redeploys in seconds.
Next (next quarter)Threat model each new feature with the four questions, and turn each risk into a test.Never.
NextSplit checks into a fast tier and a stamped release gate; add a post-release watch window and the capped fix loop.The whole suite already runs in under a minute.
NextFuzz every parser of outside input, and run dynamic tests against every network-facing surface.Nothing built takes outside input.
Later (when budget or size allows)Signed build provenance (SLSA Build Level 2), mutation testing, load testing and a yearly outside review.The software isn’t distributed to others or exposed to the internet.

How this is put together

Ridgeline is hypothetical, used to make each control concrete; any resemblance to a real organization is coincidental. The hallucinated-package figures are measured results from the cited study. Every NIST SSDF practice ID was checked against the practice titles in the full SP 800-218 text. The SOC 2 criteria references were checked against a secondary summary of the AICPA criteria, labeled as such below. Tool and vendor choices are left out on purpose: the gates matter more than the brands that run them. The OWASP mappings use SAMM v2, ASVS 5.0 and the Top 10 CI/CD Security Risks; the CSSLP domains follow the ISC2 exam outline effective 15 September 2023. Where a stage has no direct entry in a framework, the table says so rather than forcing a fit. For the supply-chain side of DevSecOps pipelines, NIST SP 800-204D (February 2024) is the deeper reference. Mapping a control to a framework shows where it fits; it is not a compliance claim.

Bottom line

Make failure loud, make every change undo itself, and make sure nobody approves their own work, including an AI assistant and the pipeline agent that fixes a failed release. Start with the four fundamentals this month; add the rest a stage at a time.

Sources

  1. NIST, SP 800-218, Secure Software Development Framework (SSDF) Version 1.1, final, February 2022. csrc.nist.gov
  2. NIST, SP 800-218 full text (PDF), practice titles PO.1 through RV.3. nvlpubs.nist.gov
  3. NIST, SSDF project page: practice groups and the SP 800-218A profile for generative-AI development. csrc.nist.gov
  4. Threat Modeling Manifesto: the four key questions. www.threatmodelingmanifesto.org
  5. SLSA v1.0, build levels. slsa.dev
  6. IETF, RFC 9116, A File Format to Aid in Security Vulnerability Disclosure (security.txt), April 2022. www.rfc-editor.org
  7. Spracklen et al., “We Have a Package for You! A Comprehensive Analysis of Package Hallucinations by Code Generating LLMs,” USENIX Security 2025. arxiv.org
  8. The New Stack, “Slopsquatting: the newest threat to your AI-generated code” (repeat-run and per-model figures). thenewstack.io
  9. Open Security Architecture, SOC 2 Trust Services Criteria (secondary summary of the AICPA criteria CC8.1, A1.2, A1.3). opensecurityarchitecture.org
  10. OWASP, Top 10 CI/CD Security Risks (CICD-SEC-1 through CICD-SEC-10). owasp.org
  11. OWASP, Software Assurance Maturity Model (SAMM) v2: business functions and security practices. owaspsamm.org
  12. OWASP, Application Security Verification Standard (ASVS) 5.0.0, 30 May 2025. asvs.owasp.org
  13. ISC2, CSSLP Certification Exam Outline, effective 15 September 2023: eight domains. www.isc2.org
  14. NIST, SP 800-204D, Strategies for the Integration of Software Supply Chain Security in DevSecOps CI/CD Pipelines, February 2024. csrc.nist.gov

Provenance: written by Fezz with Claude (Anthropic) on 23 October 2026; figures and framework references re-verified against the linked sources that day. Threat Vector Management is not affiliated with any company operating under the name “ThreatVector.”

Get the next one first

New Threat Briefs and Deep Dives, delivered to your feed reader the moment they publish. No sign-up, no email, no tracking.

Follow Insights

Fixed-scope advisory

Secure Development Gate Briefing

A working session with engineering and security leads on which gates to put in front of a release, and in what order.

Fixed scope, fixed fee, quoted before we start. Your team or a partner we’ve vetted does the hands-on work; we advise.

Partner disclosure: we only introduce partners we’ve vetted and trust. If a partner pays us for an introduction, we tell you before you decide. It never changes who we recommend.