AiOpsOne

The DevSecOps Pipeline Cheatsheet

Every gate, the tool that owns it, and what should fail the build versus what should merely report — distilled from a real six-gate pipeline run against a deliberately vulnerable app. Every number verified against a real run.

The six gates

GateTool that owns itWhat it catchesFail vs reportTrigger
Secretsgitleaks (+ GitGuardian/ggshield)Committed credentials, high-entropy stringsBLOCK on newPR (diff) + scheduled full-history
SASTSemgrep + your own sink rules (CodeQL / Snyk Code)Injection, XSS, hardcoded secrets in your codeBLOCK on ERROREvery PR
SCATrivy fs (+ Dependabot to remediate)Vulnerable dependenciesBLOCK HIGH/CRIT, --ignore-unfixedPR + Dependabot PRs
IaCCheckov (gate) + trivy configPublic buckets, wildcard IAM, open security groupsBLOCKOn **.tf change
Containerhadolint + Dockle + Trivy imageDockerfile smells, CIS, image CVEs, secrets in a layerBLOCK (Dockle fatal, Trivy HIGH/CRIT)On docker/** change
DASTZAP baseline (PR); ZAP full + Nuclei (scheduled)Vulnerabilities in the running appbaseline REPORTS; active on schedulePR (baseline) + scheduled (active)

The one rule for what blocks

Block on findings that are specific, actionable, and low-false-positive. Report everything else. Gate on fixable findings only (--ignore-unfixed / --only-fixed) — a gate that fires on things people cannot fix gets switched off, and a bypassed gate is worth less than no gate because it looks like coverage.

Fast — every pull request

  • gitleaks (scans the diff)
  • Semgrep (auto rules + your sink rules)
  • Trivy fs — dependencies
  • Checkov — Terraform
  • hadolint + Dockle + Trivy image
  • ZAP baseline (passive, -I)

Slow — on a schedule

  • Full-history secrets scan (the diff gate misses history)
  • ZAP full/active scan (it is literally an attack)
  • Nuclei with your own templates
  • Image re-scan — new CVEs land against old builds

Active scans never gate a PR someone is waiting on.

Green is not safe — read what a gate actually scanned

Green checkWhy it is green — and why that is not "secure"
ZAP baseline — 0 failuresPassive: it never sends an attack. Zero failures on an app with a working SQL injection. A smoke alarm that did not go off, on a fire it cannot see.
terraform validate — SuccessSyntax only. Passes on a public S3 bucket, an Action:"*" IAM policy, and a security group open to the world. Valid is not secure.
gitleaks on push — no leaksScans the push diff (often 1 commit), not history. A secret already in main is out of scope — caught only by the scheduled full-history scan.
SBOM job — successIt produces the bill of materials; it does not gate. Green means "the record exists", not "the image is safe".

Tool status — 2026 (re-check quarterly)

Alive & maintained: Trivy, Checkov, Grype, Syft, Semgrep, gitleaks, hadolint, Dockle, ZAP, Nuclei, CodeQL, Dependabot.

Frozen — do not rely on: tfsec (folded into Trivy; last release March 2026). Migrate to Checkov — Trivy's config scanner has no IAM-wildcard rule, so following the official tfsec→Trivy path silently drops a full-admin finding.

Archived — remove: Terrascan (Nov 2025).

Check it yourself, don't trust a banner:
curl -s https://api.github.com/repos/<org>/<repo>
Read archived and pushed_at. A frozen project is more dangerous than an archived one — it still looks alive.

Never publish a raw scan count

On the identical image, same afternoon: Trivy 7,696 · Grype 3,995 · Docker Scout 836. A CVE count is a fact about your scanner and the date, not your image. Gate on one tool, audit with another, and never put a raw number in an SLA or a board slide without naming the tool and the date beside it.

Copy-paste — the workflows are public

Every workflow behind this cheatsheet runs for real on the intentionally-vulnerable lab. Clone it, read the YAML, reuse it:

One repo, one team → monolith. Many repos or owners → reusable workflows. Most orgs run both.