Lesson 29 / 31

DevSecOps Cheat Sheet

Recall the key controls for each lifecycle stage and the tool category that implements each one.

By · 15 years in web development

One page to revise from

Plan: threat model with a data-flow diagram, trust boundaries and STRIDE; write testable security requirements (ASVS) and abuse cases. Code: parameterised queries, allow-list validation, context-aware output encoding, no secrets in code; pre-commit secret scanning. Pull request: SAST (Semgrep, CodeQL), SCA (npm audit, pip-audit, OSV-Scanner), IaC scanning (Checkov, Trivy config), secret scanning, review of authorisation logic. Build: build once, minimal non-root images, multi-stage builds, image scanning (Trivy, Grype), SBOM (CycloneDX or SPDX), signing (cosign) and provenance (SLSA). CI hardening: least-privilege tokens, actions pinned to SHAs, OIDC instead of stored keys, no untrusted code in pull_request_target. Deploy: verify signatures, policy as code (OPA, Kyverno), Pod Security Standards. Run: DAST on staging, least-privilege IAM, CSPM, central logging, detection, incident runbooks. Manage: triage with CVSS, EPSS, KEV and exposure; SLAs; measure time to remediate.

The whole course on one line

Revise in lifecycle order: plan, code, build, deploy and run, recalling two or three controls for each stage.

Five connected stages: plan, code, build, deploy, run.
Figure 10.1: plan -> code -> build -> deploy -> run, the order to revise the controls in.

A release job, step by step

The build-stage controls from the cheat sheet, in order: build and push, resolve the digest, scan, generate the SBOM, then sign and attest by digest. Run it with set -e so any failing step stops the job.

IMAGE=registry.example.com/shop/api
GIT_SHA=$(git rev-parse --short HEAD)
docker build -t "$IMAGE:$GIT_SHA" . && docker push "$IMAGE:$GIT_SHA"
DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$IMAGE:$GIT_SHA")
trivy image --severity HIGH,CRITICAL --ignore-unfixed --exit-code 1 "$DIGEST"
trivy image --format cyclonedx --output sbom.cdx.json "$DIGEST"
cosign sign --yes "$DIGEST"
cosign attest --yes --type cyclonedx --predicate sbom.cdx.json "$DIGEST"

Memorise by stage, not by tool

Tool names change. If you can explain which stage, what it checks and what happens on failure, you can map any new tool into that picture.

Quick check: At which stage should an SBOM ideally be generated?

  • Once a year during an audit
  • Only after an incident
  • By hand from the README
  • During the build, for each release artefact
Answer

During the build, for each release artefact — Generating it in the build guarantees it matches exactly what was shipped.