# DevSecOps — Part 1: Fundamentals & Shift-Left Security

> **Series:** DevSecOps (1 of 6)
> **Part 1:** This file — Fundamentals & Shift-Left Security
> **Part 2:** `02-sast-dast-sca.md` — SAST, DAST, SCA & Dependency Scanning
> **Part 3:** `03-container-and-kubernetes-security.md` — Container & Kubernetes Security
> **Part 4:** `04-secrets-management-and-iam.md` — Secrets Management & IAM
> **Part 5:** `05-cicd-pipeline-security-and-supply-chain.md` — CI/CD & Supply Chain Security
> **Part 6:** `06-compliance-and-cheatsheet.md` — Compliance Frameworks & Master Cheat Sheet
> **Questions:** `questions.md`

## Table of Contents

1. [What DevSecOps Actually Means](#what-devsecops-actually-means)
2. [Why "Bolt-On" Security Failed](#why-bolt-on-security-failed)
3. [Shift-Left, Explained Simply](#shift-left-explained-simply)
4. [The Cost-of-a-Bug Curve](#the-cost-of-a-bug-curve)
5. [The DevSecOps Pipeline, End to End](#the-devsecops-pipeline-end-to-end)
6. [Threat Modeling — Thinking Like an Attacker on Purpose](#threat-modeling--thinking-like-an-attacker-on-purpose)
7. [STRIDE — A Practical Threat Modeling Framework](#stride--a-practical-threat-modeling-framework)
8. [The Shared Responsibility Model](#the-shared-responsibility-model)
9. [Security as Code](#security-as-code)
10. [The Three Pillars of DevSecOps Culture](#the-three-pillars-of-devsecops-culture)
11. [A Realistic DevSecOps Maturity Model](#a-realistic-devsecops-maturity-model)
12. [Common Mistakes](#common-mistakes)
13. [Worked Practice Problems](#worked-practice-problems)
14. [Summary and What's Next](#summary-and-whats-next)

---

## What DevSecOps Actually Means

DevSecOps takes the DevOps idea ("dev and ops collaborate instead of working in silos") and adds one more group to the collaboration: **security**. The core belief: **security isn't a separate team's job that happens at the very end — it's everyone's job, built into every stage of building and running software.**

```mermaid
graph LR
    Old["OLD WAY:<br/>Dev builds → Ops deploys →<br/>Security reviews<br/>(at the very end, separately)"] --> OldProb["❌ Security found LATE,<br/>often after code is already<br/>written or even in production —<br/>expensive to fix, creates<br/>friction between teams"]

    New["DEVSECOPS:<br/>Dev + Ops + Security work<br/>TOGETHER, security checks<br/>run continuously at EVERY<br/>stage"] --> NewGood["✅ Issues found EARLY,<br/>cheap to fix, security<br/>becomes a shared habit<br/>instead of a gatekeeper"]
```

**Simple analogy:** imagine building a house. The old way is: build the entire house, then bring in an inspector at the very end who says "actually, this wiring is unsafe, tear down this wall." DevSecOps is like having the electrical inspector check the wiring *as it's being installed*, catching the problem in five minutes instead of after the drywall is already up.

---

## Why "Bolt-On" Security Failed

For years, the standard model was: developers build features, and a separate security team reviews everything right before release — often called "gate-based" security.

```mermaid
sequenceDiagram
    participant Dev as Developers
    participant Sec as Security Team
    participant Prod as Production

    Dev->>Dev: Build feature (weeks)
    Dev->>Sec: Submit for security review<br/>(right before release)
    Sec->>Sec: Finds a serious vulnerability
    Sec->>Dev: "This can't ship — fix it"
    Dev->>Dev: Scramble to fix under<br/>release-date pressure
    Note over Dev,Sec: Everyone frustrated -<br/>Dev feels blocked at the<br/>last minute, Security feels<br/>like the 'team that says no'
```

**Why this model breaks down at scale:** a small security team simply can't manually review every change from a large, fast-moving engineering org — they become a bottleneck. Worse, finding a serious flaw right before a release deadline creates enormous pressure to either delay the release or ship with the risk accepted quietly — neither is a good outcome. This adversarial dynamic (security = "the team that blocks releases") is exactly what DevSecOps is designed to eliminate, by making security checks **automated, continuous, and early** instead of manual and late.

---

## Shift-Left, Explained Simply

"Shift-left" simply means: **move security activities earlier in the timeline** (visually, to the "left" on a left-to-right timeline of the software development lifecycle).

```mermaid
graph LR
    Plan[Plan] --> Code[Code]
    Code --> Build[Build]
    Build --> Test[Test]
    Test --> Deploy[Deploy]
    Deploy --> Operate[Operate/Monitor]

    Old["OLD: security checks<br/>happened ONLY here"] -.-> Deploy

    New1["Shift-left: threat modeling"] -.-> Plan
    New2["Shift-left: SAST, secrets<br/>scanning in the IDE/pre-commit"] -.-> Code
    New3["Shift-left: SCA/dependency<br/>scanning in CI"] -.-> Build
    New4["Shift-left: DAST, container<br/>scanning"] -.-> Test
    New5["Shift-left: policy gates,<br/>signed artifacts"] -.-> Deploy
    New6["Runtime security,<br/>continuous monitoring"] -.-> Operate
```

**Analogy:** it's the difference between spell-checking a document as you type (catch typos in seconds) versus only running spell-check after printing 10,000 copies (catch typos too late to fix cheaply). Shift-left is spell-check-as-you-type, applied to security.

---

## The Cost-of-a-Bug Curve

This is one of the most commonly cited justifications for shift-left, and it's worth being able to explain the *reasoning*, not just quote the conclusion.

```mermaid
graph TD
    A["Bug found in DESIGN/PLANNING<br/>Cost: ~$1 (a conversation,<br/>a design change)"] --> B["Bug found in CODE REVIEW<br/>Cost: ~$10 (a few minutes<br/>of a developer's time)"]
    B --> C["Bug found in TESTING/QA<br/>Cost: ~$100 (test failure,<br/>re-work, re-test cycle)"]
    C --> D["Bug found in PRODUCTION<br/>Cost: ~$1,000+ (incident<br/>response, customer impact,<br/>emergency patch, possible<br/>data breach/compliance fallout)"]
```

**Why the cost grows so dramatically at each stage:** a design-time flaw is just an idea that hasn't been built yet — cheap to change. A production security flaw might mean an active data breach, a public disclosure, regulatory fines, incident response involving dozens of people, and reputational damage — none of which apply to a flaw caught before a single line of code shipped. **This exact curve is the single strongest, most concrete argument for shift-left**, and it's a great one to cite by name ("the cost of fixing a bug grows roughly 10x at each later stage") in an interview.

---

## The DevSecOps Pipeline, End to End

A full picture of where automated security tooling plugs into a typical CI/CD pipeline — each of these tool categories gets its own deep-dive tutorial later in this series.

```mermaid
flowchart TD
    Commit["Developer commits code"] --> PreCommit["Pre-commit hooks:<br/>secrets scanning<br/>(gitleaks, trufflehog)"]
    PreCommit --> CI["CI Pipeline triggers"]
    CI --> SAST["SAST: scan source code<br/>for vulnerability patterns<br/>(Semgrep, SonarQube)"]
    CI --> SCA["SCA: scan dependencies for<br/>known CVEs (Snyk, Dependabot)"]
    CI --> IaC["IaC scanning: check Terraform/<br/>Kubernetes manifests for<br/>misconfigurations (tfsec, Checkov)"]
    SAST --> Build["Build container image"]
    SCA --> Build
    IaC --> Build
    Build --> ImageScan["Container image scanning<br/>(Trivy, Grype)"]
    ImageScan --> Sign["Sign the artifact<br/>(cosign/Sigstore)"]
    Sign --> DAST["DAST: scan the RUNNING<br/>app in a staging env<br/>(OWASP ZAP)"]
    DAST --> Policy["Policy gate: enforce rules<br/>before deploy (OPA/Gatekeeper)"]
    Policy --> Deploy["Deploy to production"]
    Deploy --> Runtime["Runtime security monitoring<br/>(Falco, audit logs)"]
```

**A strong interview summary line:** "DevSecOps isn't one tool — it's a pipeline of automated checks, each catching a different class of problem at the earliest point it can realistically be caught: secrets before they're even committed, code-level bugs in CI, dependency CVEs before build, misconfigurations before deploy, and runtime anomalies after — with a human only pulled in when something automated actually needs judgment."

---

## Threat Modeling — Thinking Like an Attacker on Purpose

**Threat modeling** is a structured exercise, done *before* (or early in) building a system, where the team deliberately asks: "how could this be attacked, and what would we do about it?"

```mermaid
flowchart TD
    A["1. What are we building?<br/>(draw the system —<br/>data flows, trust boundaries)"] --> B["2. What can go wrong?<br/>(brainstorm threats,<br/>e.g. using STRIDE below)"]
    B --> C["3. What are we going<br/>to do about it?<br/>(design mitigations)"]
    C --> D["4. Did we do a good<br/>enough job?<br/>(review, iterate)"]
```

This four-question framing (attributed to Adam Shostack, a well-known threat modeling practitioner) is a simple, memorable structure worth citing by name in an interview.

### A Simple Worked Example: Threat Modeling a Login Feature

```mermaid
graph TD
    Feature["Feature: User Login"] --> DFD["Draw the data flow:<br/>Browser → Load Balancer →<br/>Auth Service → Database"]
    DFD --> Threats["Brainstorm threats at<br/>EACH boundary:"]
    Threats --> T1["Browser↔LB: could traffic<br/>be intercepted? → Require HTTPS"]
    Threats --> T2["LB↔Auth Service: could an<br/>attacker guess passwords?<br/>→ Rate limit login attempts"]
    Threats --> T3["Auth Service↔DB: could a<br/>SQL injection leak<br/>passwords? → Parameterized<br/>queries + hashed passwords"]
```

---

## STRIDE — A Practical Threat Modeling Framework

**STRIDE** (created at Microsoft) is the single most commonly cited threat modeling checklist in interviews — a mnemonic for six categories of things that can go wrong.

```mermaid
graph TD
    STRIDE[STRIDE] --> S["Spoofing —<br/>pretending to be someone/<br/>something you're not"]
    STRIDE --> T["Tampering —<br/>maliciously modifying<br/>data or code"]
    STRIDE --> R["Repudiation —<br/>denying you did something,<br/>with no way to prove otherwise"]
    STRIDE --> I["Information Disclosure —<br/>exposing data to someone<br/>who shouldn't see it"]
    STRIDE --> D["Denial of Service —<br/>making a system unavailable<br/>to legitimate users"]
    STRIDE --> E["Elevation of Privilege —<br/>gaining more access<br/>than you should have"]
```

| Threat | Plain-English Question | Example Mitigation |
|---|---|---|
| **S**poofing | "Could someone pretend to be a legitimate user or service?" | Strong authentication, mutual TLS between services |
| **T**ampering | "Could someone alter data or code in transit or at rest?" | Checksums, signed artifacts, integrity checks, HTTPS |
| **R**epudiation | "Could someone do something bad and deny it, with no evidence?" | Audit logging, non-repudiable signatures |
| **I**nformation Disclosure | "Could sensitive data leak to someone who shouldn't see it?" | Encryption at rest/in transit, least-privilege access controls |
| **D**enial of Service | "Could someone make this unavailable to real users?" | Rate limiting, autoscaling, DDoS protection (ties to the Resilience Patterns tutorial) |
| **E**levation of Privilege | "Could someone gain more access than they should have?" | Least privilege, input validation, proper authorization checks (not just authentication) |

**A strong interview move:** if asked to threat-model any system on the spot, walk through each STRIDE category one at a time against the system's actual data flow — this is a repeatable, structured method that works for basically any system, and demonstrates real methodology rather than random guessing.

---

## The Shared Responsibility Model

A foundational concept, especially relevant in cloud environments, and a very common interview topic on its own.

```mermaid
graph TD
    subgraph "AWS/Cloud Provider Responsibility"
    Cloud["Security OF the cloud:<br/>physical data centers,<br/>hardware, hypervisor,<br/>managed service internals"]
    end
    subgraph "Your (Customer) Responsibility"
    Customer["Security IN the cloud:<br/>your data, IAM configuration,<br/>OS patching (for IaaS),<br/>network configuration,<br/>application code, encryption<br/>settings you choose"]
    end
```

**The line moves depending on the service model:**

| Service Model | Example | What the Provider Handles | What YOU Handle |
|---|---|---|---|
| **IaaS** (Infrastructure as a Service) | EC2 VMs | Physical hardware, hypervisor | OS patching, network config, app code, data |
| **PaaS** (Platform as a Service) | AWS RDS, Elastic Beanstalk | Above + OS, runtime patching | App code, data, access config |
| **SaaS** (Software as a Service) | Google Workspace | Above + the application itself | Your data, user access management |

**The most common, real-world interview trap this exposes:** many real breaches happen not because the cloud provider was hacked, but because a customer **misconfigured their own side** of the shared responsibility line — e.g., a publicly-exposed S3 bucket, or overly permissive IAM roles. **"The cloud provider secures the cloud; you secure what you put in it and how you configure it"** is the one-line answer worth having ready.

---

## Security as Code

The DevSecOps philosophy applied concretely: instead of a security policy living in a PDF document nobody reads, express it as **code** that's automatically enforced.

```mermaid
graph TD
    Old["OLD: Security policy is<br/>a PDF/wiki page:<br/>'S3 buckets must not be<br/>publicly readable'"] --> OldProb["❌ Relies on humans<br/>remembering to check,<br/>manually, every time"]

    New["SECURITY AS CODE:<br/>same rule, written as an<br/>automated policy check<br/>(e.g. OPA/Rego, tfsec rule)"] --> NewGood["✅ Automatically enforced<br/>on EVERY change, EVERY<br/>time, with zero reliance<br/>on human memory"]
```

A concrete example — a policy written in **Open Policy Agent's Rego language** (covered further in Part 5), enforcing "no S3 bucket may be publicly readable":

```rego
package terraform.s3

deny[msg] {
  input.resource_type == "aws_s3_bucket"
  input.values.acl == "public-read"
  msg := sprintf("S3 bucket '%s' must not have public-read ACL", [input.address])
}
```

```bash
# Running this policy check against a Terraform plan, in CI
terraform plan -out=tfplan.binary
terraform show -json tfplan.binary > tfplan.json
opa eval --data policy.rego --input tfplan.json "data.terraform.s3.deny"
```

**This is the practical, hands-on definition of "security as code"** worth demonstrating in an interview — not an abstract philosophy, but literally writing enforceable rules as version-controlled code, run automatically in a pipeline, exactly like any other test.

---

## The Three Pillars of DevSecOps Culture

Tooling alone doesn't make an organization "DevSecOps" — the culture shift matters just as much, and interviewers specifically probe for whether you understand this isn't purely a tooling problem.

```mermaid
graph TD
    Culture[DevSecOps Culture] --> P1["Shared Ownership —<br/>security is EVERYONE'S<br/>job, not just the<br/>security team's"]
    Culture --> P2["Fast Feedback —<br/>developers learn about<br/>a security issue in<br/>MINUTES (in their IDE/PR),<br/>not weeks later"]
    Culture --> P3["Blameless, Just Like<br/>Postmortems — a developer<br/>who introduces a vulnerability<br/>isn't punished; the SYSTEM<br/>should have caught it<br/>automatically, earlier"]
```

**The direct tie-in worth naming:** this third pillar connects directly to the **blameless postmortem culture** from the SRE Fundamentals series — a security vulnerability that reaches production is treated the same way an outage is: a systemic gap (missing automated check, unclear guidance, a gap in the pipeline) to be fixed, not an individual's fault to assign.

---

## A Realistic DevSecOps Maturity Model

A useful framework for describing "how mature is this org's security practice" — a genuinely common interview question when discussing past experience.

```mermaid
graph TD
    L0["Level 0: Ad hoc<br/>No automated security<br/>checks; manual review only,<br/>if any, right before release"] --> L1
    L1["Level 1: Basic Scanning<br/>SAST/dependency scanning<br/>exists but is manual/optional,<br/>often ignored"] --> L2
    L2["Level 2: Automated Gates<br/>Security scans run<br/>automatically in CI;<br/>CRITICAL findings block<br/>the pipeline"] --> L3
    L3["Level 3: Shift-Left + Runtime<br/>Threat modeling for new<br/>features; secrets scanning<br/>pre-commit; runtime security<br/>monitoring in production"] --> L4
    L4["Level 4: Continuous & Adaptive<br/>Security policies as code;<br/>automated remediation;<br/>metrics-driven (e.g. MTTR<br/>for vulnerabilities tracked<br/>like an SLO)"]
```

**A strong interview answer** to "how would you improve security maturity at a company currently doing manual, ad hoc reviews" walks through this progression explicitly — you don't jump straight to Level 4; you build automated gates first (Level 2), then layer in shift-left practices and runtime monitoring (Level 3), before tackling the more sophisticated continuous/adaptive practices (Level 4).

---

## Common Mistakes

| Mistake | Why It's Wrong | Fix |
|---|---|---|
| Treating DevSecOps as "buy a scanning tool and we're done" | Tools alone don't fix a culture where security is seen as someone else's job | Combine automated tooling WITH cultural shifts (shared ownership, fast feedback, blameless response) |
| Running security scans but not gating the pipeline on critical findings | Scans that don't block anything just become ignored noise, exactly like alert fatigue | Fail the build/block the merge on critical/high-severity findings; tune thresholds to avoid excessive noise |
| Only scanning right before production release | Defeats the entire purpose of shift-left — issues are still found late and expensively | Scan at every stage: pre-commit, PR, build, pre-deploy, and runtime |
| Punishing developers for introducing a vulnerability that reached production | Discourages transparency, exactly like a blame-focused postmortem culture | Treat it as a systemic gap in automated checks to be fixed, not an individual failing |
| Assuming the cloud provider secures everything | Misunderstands the shared responsibility model — most real cloud breaches are customer-side misconfigurations | Explicitly know and own your side of the shared responsibility line |
| No threat modeling for new features, only for major new systems | Misses realistic threats introduced incrementally by smaller features | Do lightweight threat modeling (even 15-30 minutes with STRIDE) for any feature touching sensitive data or new trust boundaries |

---

## Worked Practice Problems

**Problem 1:** A company currently only runs a manual security review two weeks before each quarterly release. Engineering wants to move to a bi-weekly release cadence. What's the core problem, and how would you fix it using shift-left principles?

*Answer:* The core problem is that the manual review process doesn't scale with a faster release cadence — a security team can't manually review everything twice as often, and squeezing a full manual review into a shorter cycle either delays releases or gets skipped. The shift-left fix: replace (or heavily supplement) the manual gate with automated checks running continuously throughout development — SAST/secrets scanning on every commit, SCA on every dependency change, container/IaC scanning before every deploy — so most issues are caught and fixed in minutes as code is written, and the remaining manual review time (if any) is reserved for genuinely complex, high-risk changes rather than routine ones.

**Problem 2:** During a threat-modeling session for a new "password reset" feature, walk through STRIDE and name at least one plausible threat per category.
*Answer:*
- Spoofing: an attacker requests a password reset for a victim's email, impersonating them.
- Tampering: an attacker intercepts and modifies the reset token in transit.
- Repudiation: a user claims they never requested a reset, with no log to confirm or deny it.
- Information Disclosure: the reset flow leaks whether an email address is registered (an enumeration vulnerability).
- Denial of Service: an attacker floods the reset endpoint, exhausting email-sending quota or rate limits for legitimate users.
- Elevation of Privilege: a flawed reset token allows resetting a different account's password than the one initially requested.

**Problem 3:** An engineer pushes a commit containing a hardcoded AWS access key, which is discovered by a colleague three days later during code review, after the commit has already been merged and deployed. What's the systemic (not individual) fix?

*Answer:* This is a shift-left gap — the check that should have caught this needs to run *before* the commit is even merged, ideally before it's even pushed. The concrete fix: add a pre-commit hook (or a mandatory CI check that blocks merges) using a secrets-scanning tool (like gitleaks or trufflehog, covered in Part 4) so a hardcoded credential is caught in seconds, locally or in the PR, rather than discovered days later by chance during manual review — and immediately rotate the exposed key regardless, since it must be treated as compromised the moment it was pushed to a shared repository.

---

## Summary and What's Next

- **DevSecOps** extends DevOps by making security a shared, continuous responsibility across dev, ops, and security — not a separate gate at the end.
- **Shift-left** means moving security checks earlier in the development timeline, because the **cost of fixing a bug grows roughly 10x at each later stage** — design-time is cheap, production is expensive (and can mean a real breach).
- A mature DevSecOps pipeline layers automated checks at every stage: secrets scanning pre-commit, SAST/SCA in CI, container/IaC scanning before deploy, and runtime monitoring after.
- **Threat modeling** (using a framework like **STRIDE**: Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege) is a structured, repeatable way to think like an attacker before building something, not after.
- The **shared responsibility model** clarifies exactly where a cloud provider's security obligations end and your own configuration/data responsibility begins — most real cloud breaches are customer-side misconfigurations, not provider failures.
- **Security as code** means expressing policies as automatically-enforced, version-controlled rules (e.g., OPA/Rego) instead of documents nobody reads.
- DevSecOps culture rests on **shared ownership, fast feedback, and a blameless response** to vulnerabilities — directly mirroring the blameless postmortem culture from the SRE Fundamentals series.

**Continue to Part 2** (`02-sast-dast-sca.md`) for a hands-on deep dive into the actual automated scanning categories — SAST, DAST, and SCA — with real tool names, commands, and CI examples.
