A DevSecOps checklist is only useful if it is organized by pipeline stage and enforces the smallest set of controls that actually reduce risk, because a checklist that lists fifty aspirational items gets skimmed and ignored while one that gates five things at the right moments changes behavior. The goal of DevSecOps is to move security decisions to where and when they are cheapest to act on, which means the checklist below is structured around the developer's workflow, from the moment code is written to the moment it runs in production, rather than as a generic pile of good intentions.
The failure mode of most DevSecOps best practices checklists is that they read like a compliance framework, comprehensive, abstract, and impossible to act on. This one is deliberately opinionated about what to gate versus what to merely surface, because the difference between a security control that works and one that gets bypassed is usually whether it blocks the build or just files a report nobody reads.
Pre-commit and code stage
Security starts before code reaches the repository. The controls here are cheap because nothing has been built yet.
Secret scanning on commit. A pre-commit hook or server-side scan that blocks commits containing API keys, tokens, or private keys. A leaked secret in git history is expensive to remediate because it lives in every clone forever, so catching it at commit time is worth the minor friction. Rotate any secret that does slip through, do not just delete the commit.
Dependency check on new additions. When a developer adds a dependency, flag it if it carries a known vulnerability, an incompatible license, or poor maintenance signals, at pull-request time, before it merges. Catching a bad dependency here costs a code review comment; catching it after release costs an incident.
IaC and config linting. If the change touches Terraform, Kubernetes manifests, or Dockerfiles, lint them for insecure defaults, a public S3 bucket, a privileged container, a missing resource limit, before merge.
Code review with security awareness. At least one reviewer, and for changes touching auth, crypto, or input handling, a reviewer who knows what to look for. Automated static analysis supplements this but does not replace it.
Build and test stage
Once code is building, the controls shift to the artifact and its composition.
Software composition analysis on the full tree. Resolve the complete transitive dependency graph and check it against advisory databases, ideally with reachability so you gate on vulnerabilities your code actually invokes rather than every CVE in every transitive package. An SCA step here is the highest-leverage supply-chain control most teams can add.
Static application security testing (SAST). Run SAST on your source to catch injection, unsafe deserialization, and similar code-level flaws. Tune it aggressively, an untuned SAST tool produces enough false positives to train your team to ignore it.
Container image scanning. If you build images, scan the assembled image before pushing to the registry so you catch OS-package CVEs the base image contributed, on top of the application dependencies.
SBOM generation. Produce a CycloneDX or SPDX bill of materials for each build artifact and store it. This is both a compliance deliverable and the thing that lets you answer "which of our releases contain this newly disclosed CVE" without rescanning everything.
Reproducible, pinned builds. Install from a committed lockfile (npm ci, pip install -r with hashes, and equivalents) so the build is deterministic and a floating version range cannot inject a compromised package.
Deploy stage
The controls here decide whether a risky artifact reaches production.
Policy gate on findings. Define an explicit policy, for example, block promotion on any critical, reachable, KEV-listed vulnerability, and enforce it as a pipeline gate. The policy has to be written down and owned; an implicit gate in someone's head does not survive turnover.
Artifact signing and verification. Sign build artifacts and container images (with something like Sigstore/cosign) and verify signatures at deploy time so only artifacts your pipeline produced can be deployed. This closes the gap where a compromised registry serves a substituted image.
Least-privilege deploy credentials. The deploy process should have exactly the permissions it needs and no standing broad access. A compromised CI runner with admin cloud credentials is a company-ending event; scope the credentials down and prefer short-lived, workload-identity tokens over long-lived keys.
Environment configuration review. Confirm secrets come from a secrets manager, not baked into images or environment files committed to the repo, and that production config differs from staging in the ways it should (stricter limits, real TLS, no debug endpoints).
Runtime stage
Security does not stop at deploy. The runtime controls catch what everything upstream missed.
Least-privilege runtime. Containers run non-root, with dropped capabilities, read-only root filesystems where feasible, and resource limits. Admission policy rejects workloads that do not meet the baseline.
Continuous vulnerability monitoring. A CVE disclosed today affects images you deployed last month. Continuously match new advisories against the SBOMs of what is actually running, so a fresh critical vulnerability surfaces as real exposure rather than being missed until the next scan cycle.
Logging and detection. Capture security-relevant events, auth failures, privilege changes, unexpected egress, and feed them somewhere that can alert. You cannot respond to what you cannot see.
Incident readiness. Have a documented path from "we found a compromised dependency in production" to "it is contained and remediated," and rehearse it. The investigation steps for a CI/CD compromise are worth working through before you need them.
How do I roll this out without stalling delivery?
Do not turn everything on at once as a hard gate. Start every new control in report-only mode, measure the finding volume and the false-positive rate, tune, and only then flip it to blocking. Introduce gates one stage at a time, and pair each new gate with clear remediation guidance so a blocked developer knows exactly what to do rather than filing a ticket to disable the check. A DevSecOps checklist that developers experience as help rather than obstruction is one that survives; one that blocks builds with unactionable noise gets bypassed within a sprint. If you are building the muscle across teams, our Academy has stage-by-stage walkthroughs for wiring these gates into common CI systems.
FAQ
What is the difference between a DevSecOps checklist and a compliance checklist?
A compliance checklist verifies you meet an external standard's requirements at a point in time. A DevSecOps checklist embeds security controls into the delivery pipeline so risk is reduced continuously as code flows to production. They overlap, good DevSecOps produces much of the evidence compliance needs, but the DevSecOps checklist is oriented around developer workflow and enforcement, not audit attestation.
Which DevSecOps controls should actually block the build?
Gate on the high-confidence, high-impact items: committed secrets, critical and reachable dependency vulnerabilities, unsigned artifacts, and IaC misconfigurations with clear security impact. Surface everything else as a warning or ticket. Blocking on low-confidence findings trains teams to bypass the gate, which is worse than not having it.
How do I keep a DevSecOps checklist from becoming shelfware?
Enforce it in the pipeline rather than as a document people are supposed to remember, start controls in report-only mode and tune before enforcing, and pair every gate with actionable remediation guidance. A control that runs automatically and tells developers exactly how to fix a finding changes behavior; a PDF of best practices does not.
Does DevSecOps replace a dedicated security team?
No. DevSecOps distributes routine security work into the pipeline and to developers, which frees the security team to focus on threat modeling, architecture review, incident response, and the judgment calls automation cannot make. The team's role shifts from gatekeeper to enabler, but it does not disappear.