Part 9 — The security program
Everything so far is a capability: you can secure a cloud account, a cluster, a microservice fleet, a web app, sensitive data, and you can detect and respond to attacks against all of it. A security program is the organisational machinery that makes those capabilities happen reliably, at scale, across every team, forever — not just in the lab you built for this guide. This Part is how you run that machinery.
Chapter 58 — Building an SSDLC / product-security program
In one sentence
A secure software development lifecycle embeds this guide's controls into the places engineers already work — design review, code review, CI/CD — so that security is a property of how software gets built by default, not a separate audit performed on it afterward.
Where we are
Every technical chapter in this guide assumed someone with security expertise was doing the work. A program scales that expertise across an engineering organisation that will always vastly outnumber the security team, using gates, tooling, and a multiplier: security champions embedded in each team.
How it works
Security requirements and design review — the earliest, cheapest gate:
Every new feature/service of meaningful size gets a LIGHTWEIGHT
security touchpoint at design time, tied directly to Part 1 Ch 4's
tiered threat-modeling practice:
- a "security notes" section in the design doc (Tier 0, always)
- for new services or significant changes: the Tier 1 threat-model
session, PLUS an explicit target on the OWASP APPLICATION SECURITY
VERIFICATION STANDARD (ASVS):
ASVS Level 1 baseline, every application, achievable by
following secure-coding standards alone.
ASVS Level 2 applications handling sensitive data (Part 7's
RESTRICTED tier) -- most business applications
should target this.
ASVS Level 3 high-value/critical systems (payments, auth
infrastructure, the IdP from Ch 63) -- the highest
bar, reserved for what actually needs it.
This turns "is this secure enough" from a vague question into "which
ASVS level does this system need, and does it meet it" -- a checklist
the design-review gate can actually verify.
The pipeline gates (mapping this guide's tools onto the SDLC, end to end):
PRE-COMMIT secret scanning (G1 Ch 49) as a git hook -- catches the
cheapest mistakes before they even reach a PR.
PULL REQUEST SAST (static analysis: Semgrep, CodeQL, SonarQube) --
PR-blocking for HIGH-CONFIDENCE rules only (a noisy SAST
gate that blocks merges on low-confidence findings trains
engineers to bypass or ignore it); SCA (G1 Ch 47) for
dependency vulnerabilities; IaC scanning + policy-as-code
(Part 3 Ch 11) for infrastructure changes.
PRE-DEPLOY DAST (dynamic analysis against a running staging
instance -- OWASP ZAP, or a commercial scanner) catches
what static analysis structurally can't (runtime
behaviour, auth/session issues, some of Part 6's classes);
container/image scanning and signature verification
(Part 3 Ch 13); a final policy-as-code admission gate.
POST-DEPLOY runtime detection and monitoring (Part 8) catches what
every earlier gate missed -- this is "shift right"
completing what "shift left" started, not a separate
concern.
IAST (interactive application security testing -- an instrumented
agent inside the running app during QA/testing, e.g. Contrast
Security) sits between SAST and DAST: it gets DAST's real-runtime
accuracy with SAST's code-level context (exact line, exact data flow),
at the cost of requiring the instrumentation to be present. Adopt where
the cost is justified; it's not universally necessary if your SAST+DAST
combination already gives adequate coverage.
FUZZING for parsers and other complex input-handling code (anything
from Part 6's file-upload and deserialization chapters, or a custom
binary protocol) -- continuous fuzzing (OSS-Fuzz if you're open source;
libFuzzer/AFL++ integrated into CI otherwise) finds the inputs a human
reviewer would never think to try, and is the practical answer to G1's
"formal methods, fuzzing" honest gap for the specific, high-value case
of parsing untrusted input.
Shift left AND shift right — not a choice between them:
SHIFT LEFT catch issues as early as possible (design, code, PR) --
cheaper to fix, faster feedback loop, prevents the issue from ever
reaching production.
SHIFT RIGHT observe and detect in production (Part 8) -- catches
what shift-left inevitably misses (every static/dynamic tool has
blind spots; new attack techniques emerge after your tooling was
configured; some issues only manifest under real production
conditions/load/data).
A mature program runs BOTH continuously and feeds findings from
shift-right (a real production detection, Part 8 Ch 54) BACK into
shift-left (a new SAST rule, a new design-review checklist item) --
the same feedback loop as Ch 53's hunting-to-detection pipeline,
applied to the whole SDLC.
Security champions — the multiplier that makes this scale:
ONE trained champion per engineering team, NOT a separate role -- an
engineer who already knows the team's codebase, given extra security
training and a standing responsibility: first-pass review of security
findings for their team, a conduit for the central security team's
guidance, and often the fastest path to fixing something because they
already have the context and the trust of their teammates.
Run a regular (monthly is common) champions sync: share new threats
relevant to what teams are building, review recent findings across the
org, and let champions raise what THEIR team is struggling with -- this
is where a central, necessarily-small security team's expertise
actually reaches every team, rather than bottlenecking on a handful of
people who cannot review every PR across the whole organisation.
Security debt — findings are backlog items, not a parallel universe:
A security finding that isn't tracked in the SAME system engineers use
for every other kind of work (the normal issue tracker, with the same
prioritisation and sprint-planning visibility) gets silently
deprioritised forever. Treat security findings exactly like any other
defect: triaged, assigned an SLA by risk (Ch 59), tracked to closure,
and visible in the same dashboards leadership already looks at
(Ch 62) -- a SEPARATE "security backlog" that nobody outside security
ever sees is where security debt goes to die.
Worked example
Rolling out a PR-blocking SAST gate without an engineering revolt.
NAIVE ROLLOUT: enable a SAST tool's DEFAULT rule set, block merges on
ANY finding, org-wide, on day one. Result (predictable, and common):
hundreds of low-confidence findings across every repo, engineering
teams furious at broken velocity, a flood of suppression comments
(`// nosec`, `// nolint`) added just to unblock merges -- the gate is
now WORSE than nothing, because it's trained everyone to suppress
findings reflexively rather than evaluate them.
BETTER ROLLOUT (mirrors Part 4 Ch 18's PSA rollout pattern -- the same
"audit, then enforce" discipline, applied to code scanning):
1. Enable the tool in AUDIT/REPORT-ONLY mode org-wide. Let it run for
2-3 weeks with zero blocking.
2. TUNE the rule set aggressively: disable/downgrade rules with a
high false-positive rate for YOUR codebase's actual patterns
before ever blocking on them; start with a SMALL set of
HIGH-CONFIDENCE, HIGH-SEVERITY rules (hardcoded credentials,
SQL injection via string concatenation, known-dangerous
deserialization sinks from Part 6 Ch 37) rather than the tool's
full default set.
3. Flip to BLOCKING for that small, tuned rule set, team by team
(starting with a volunteer team, ideally one with an engaged
security champion) rather than org-wide on one day.
4. Expand the blocking rule set GRADUALLY as confidence in low
false-positive rate is established, and expand team-by-team
rollout as each team's existing findings are cleared (a
blocking gate applied to a repo full of pre-existing findings
just blocks the FIRST unrelated PR someone tries to merge --
clear the backlog first, or exempt pre-existing findings and
block only NEW ones).
5. Track suppression comments as a METRIC (Ch 62) -- a rising
suppression rate is an early warning that a rule has drifted into
being too noisy again, before it becomes an engineering-trust
problem.
RESULT: the gate that ships six weeks later, covering a smaller but
TRUSTED rule set, gets far higher engineering buy-in than one rushed
out on day one covering everything -- exactly the same lesson as
admission-policy rollout in Part 4, applied to the SDLC.
Practice (75 min)
- Pick a real (or lab) repository. Add a SAST tool (Semgrep is free and fast to start with) in report-only mode; review its findings and identify which are high-confidence/high-severity vs noisy.
- Design the tiered rollout plan from the worked example for that repo: which small rule set goes blocking first, and what's the exemption/backlog- clearing plan for pre-existing findings.
- Add one PR-blocking SCA check (dependency vulnerability scanning, G1 Ch 47) and one IaC policy-as-code check (Part 3 Ch 11) to the same repo's pipeline.
- Map one real feature you've built during this guide's hands-on labs against ASVS — pick the appropriate level (1/2/3) based on its data sensitivity, and identify at least three specific ASVS requirements it currently does or doesn't meet.
- Draft a one-page "security champion" role description and a monthly sync agenda template you'd actually use.
Across the series
- Go's built-in quality gates (vet,
staticcheck,govulncheck,-race, fuzzing) in CI: Go guide, Chapters 60 and 64. The Go plan's Week 16 runs a security audit, a coverage audit, and parser fuzzing on its own code.
Common mistakes
- Blocking on a noisy tool's default rule set from day one. Trains engineers to suppress findings rather than fix them; destroys trust in the gate.
- A security backlog nobody outside security sees. Findings not tracked alongside normal engineering work get permanently deprioritised.
- Champions treated as a separate role rather than an augmentation of an existing engineer's role. Loses the context and trust advantage that makes the model work.
- Shift-left only, no shift-right. Every static/dynamic tool has blind spots; production detection (Part 8) is not optional insurance, it's the other half of the discipline.
- No ASVS (or equivalent) target level. "Is this secure enough" stays a vague, unanswerable question without a concrete checklist to verify against.
- DAST/IAST/fuzzing skipped because SAST "already covers code quality." Each catches a genuinely different class of issue; a program built on SAST alone has large blind spots (runtime behaviour, parser robustness).
Check yourself
- Map each SDLC stage (pre-commit, PR, pre-deploy, post-deploy) to the security tooling that belongs there.
- Why is a security-champions program a multiplier, and what would be lost if champions were a fully separate role from the engineering teams they support?
- What does ASVS give you that a vague "make it secure" requirement doesn't?
- Explain "shift left AND shift right" and why they're complementary rather than alternatives.
- Why does a rushed, org-wide, blocking SAST rollout typically backfire, and what's the safer rollout pattern?
- Why must security findings live in the same tracking system as other engineering work?
(Answers: Appendix G.)
Further reading
- Standard: OWASP Application Security Verification Standard (ASVS) — the full checklist and its three levels; OWASP Software Assurance Maturity Model (SAMM) for assessing your program's overall maturity.
- Standard: NIST Secure Software Development Framework (SSDF, SP 800-218) — the US government's baseline SSDLC practices, increasingly referenced in procurement requirements.
- Tools: Semgrep, CodeQL, SonarQube (SAST); OWASP ZAP (DAST); OSS-Fuzz, AFL++, libFuzzer (fuzzing) — read each tool's "getting started" and rule/ corpus-authoring guides.
- Program design: "Building a Vulnerability Disclosure/Security Champions Program" write-ups from major tech companies' engineering blogs; Alice and Bob Learn Application Security (Tanya Janca, G1 reference) — the program- building chapters specifically.