# Diagrams — Module S07: Threat Modeling Harnesses

> All Mermaid validated in Mermaid Live Editor. n8n JSON is structurally valid and importable.

---

## Diagram 1 — The Threat Modeling Harness Pipeline (n8n)

**Type**: n8n workflow (importable JSON)
**Purpose**: The primary visual — from architecture inputs (draw.io, Terraform, OpenAPI) through DFD ingestion, STRIDE analysis, mitigation generation, and issue tracking.

```json
{
  "name": "S07 — Threat Modeling Harness Pipeline",
  "nodes": [
    { "name": "Architecture Inputs", "type": "n8n-nodes-base.manualTrigger", "position": [200, 300], "notes": "draw.io XML, Mermaid, Terraform, CloudFormation, OpenAPI, source structure" },
    { "name": "Parsers (per source)", "type": "n8n-nodes-base.set", "position": [440, 300], "notes": "Each input → DFDElement + Flow. IaC authoritative; diagrams supplementary." },
    { "name": "DFD (canonical IR)", "type": "n8n-nodes-base.set", "position": [680, 300], "notes": "elements, flows, trust_boundaries. Decouples ingestion from analysis." },
    { "name": "Trust Boundary Detection", "type": "n8n-nodes-base.set", "position": [680, 150], "notes": "Internet-facing, IAM cross-account, tenant isolation. Each element → boundary; flows marked crosses_boundary." },
    { "name": "STRIDE Engine", "type": "n8n-nodes-base.set", "position": [920, 300], "notes": "Per (element, applicable category): LLM generates GROUNDED threats with attack narrative + draft CVSS." },
    { "name": "Dedup + Prioritize", "type": "n8n-nodes-base.set", "position": [1160, 300], "notes": "Semantic similarity dedup. Rank by CVSS draft score. Top threats first." },
    { "name": "Mitigation Generator", "type": "n8n-nodes-base.set", "position": [1400, 300], "notes": "Per threat: map to OWASP ASVS + CWE + cloud best practice. Concrete implementation." },
    { "name": "Issue Tracker", "type": "n8n-nodes-base.executeCommand", "position": [1640, 300], "notes": "Auto-create GitHub/Linear/Jira issues. Bidirectional status sync with threat model." },
    { "name": "Model Version Store", "type": "n8n-nodes-base.set", "position": [680, 450], "notes": "Versioned DFD snapshots. Diff two versions → re-run only on delta." }
  ],
  "connections": {
    "Architecture Inputs": { "main": [[{ "node": "Parsers (per source)", "type": "main", "index": 0 }]] },
    "Parsers (per source)": { "main": [[{ "node": "DFD (canonical IR)", "type": "main", "index": 0 }]] },
    "Trust Boundary Detection": { "main": [[{ "node": "DFD (canonical IR)", "type": "main", "index": 0 }]] },
    "DFD (canonical IR)": { "main": [[{ "node": "STRIDE Engine", "type": "main", "index": 0 }]] },
    "DFD (canonical IR)": { "main": [[{ "node": "Model Version Store", "type": "main", "index": 0 }]] },
    "STRIDE Engine": { "main": [[{ "node": "Dedup + Prioritize", "type": "main", "index": 0 }]] },
    "Dedup + Prioritize": { "main": [[{ "node": "Mitigation Generator", "type": "main", "index": 0 }]] },
    "Mitigation Generator": { "main": [[{ "node": "Issue Tracker", "type": "main", "index": 0 }]] }
  }
}
```

**Reading the diagram**: Left to right. Architecture inputs (draw.io, Terraform, OpenAPI) are parsed per-source into the canonical DFD representation. Trust boundary detection runs alongside, assigning each element to a boundary and marking flows that cross boundaries. The STRIDE engine runs per (element, applicable category) — the LLM generates grounded threats with attack narratives and draft CVSS vectors. Dedup collapses similar threats; prioritization ranks by CVSS. Mitigation generation maps each threat to OWASP, CWE, and cloud best practices with a concrete implementation. Issues auto-create in the engineering tracker. The model version store holds snapshots; on the next run, the harness diffs versions and re-runs analysis only on the delta.

---

## Diagram 2 — STRIDE Per Element (the applicability matrix)

**Type**: Mermaid (flowchart)
**Purpose**: Shows which STRIDE categories apply to which DFD element types — the scoping that prevents irrelevant threats.

```mermaid
flowchart LR
    EXT["External Actor"]
    PROC["Process / Service"]
    DS["Data Store"]
    FLOW["Data Flow"]

    EXT -->|"Spoofing, Repudiation"| STRIDE["STRIDE"]
    PROC -->|"ALL SIX categories"| STRIDE
    DS -->|"Tampering, Repudiation,<br/>Info Disclosure, DoS"| STRIDE
    FLOW -->|"Tampering,<br/>Info Disclosure, DoS"| STRIDE

    STRIDE --> OUT["Grounded threats<br/>per applicable category"]

    style PROC fill:#14141f,stroke:#5eead4,color:#5eead4
    style STRIDE fill:#0d1b2a,stroke:#1b4f72,color:#e4e4e8
    style OUT fill:#0d2818,stroke:#1e8449,color:#82e0aa
```

**Reading the diagram**: STRIDE is not applied uniformly. External actors are analyzed for spoofing and repudiation only — you don't elevate privilege on something already outside the boundary. Processes and services get all six categories (they are the richest attack surface). Data stores get tampering, repudiation, information disclosure, and denial of service — not spoofing. Data flows get tampering, information disclosure, and denial of service. This scoping prevents the engine from generating threats that don't apply (e.g. "spoof the database"), keeping the threat list focused and credible.

---

## Diagram 3 — Grounded Threat Generation (context matters)

**Type**: Mermaid (flowchart)
**Purpose**: Shows why grounding in specific technologies + flows is load-bearing — the difference between a useless generic threat and an actionable specific one.

```mermaid
flowchart TD
    PAIR["Element + STRIDE category<br/>e.g. API Gateway service + Spoofing"]
    GENERIC["Generic generator<br/>'An attacker might spoof<br/>authentication'"]
    USELESS["Useless — applies to<br/>any service, no action"]
    GROUNDED["Grounded generator<br/>(LLM + technologies + flows)"]
    CONTEXT["Context: Cognito user pool,<br/>Lambda backend, PII crossing<br/>internet→VPC boundary"]
    SPECIFIC["Specific: 'Attacker with stolen Cognito<br/>creds calls Lambda directly, bypassing<br/>API Gateway rate limit + WAF'<br/>CVSS AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:L"]

    PAIR --> GENERIC --> USELESS
    PAIR --> GROUNDED
    CONTEXT --> GROUNDED
    GROUNDED --> SPECIFIC

    style GENERIC fill:#2a0d0d,stroke:#a00000,color:#f08080
    style USELESS fill:#2a0d0d,stroke:#a00000,color:#f08080
    style GROUNDED fill:#14141f,stroke:#5eead4,color:#5eead4
    style SPECIFIC fill:#0d2818,stroke:#1e8449,color:#82e0aa
```

**Reading the diagram**: Given the same (element, category) pair, a generic template produces a useless threat — "an attacker might spoof authentication" applies to any service and prompts no action. The grounded LLM generator, fed with the element's specific technologies (Cognito, Lambda) and the specific flows crossing its trust boundary (PII crossing internet-to-VPC), produces an actionable threat with a concrete attack narrative and a draft CVSS vector. Grounding is the load-bearing instruction that separates signal from platitude.

---

## Diagram 4 — Threat Model Version Diff

**Type**: Mermaid (flowchart)
**Purpose**: Shows how diffing two model versions makes continuous threat modeling tractable — analysis runs on the delta, not the whole model.

```mermaid
flowchart LR
    V1["Model v1<br/>(last run)"]
    V2["Model v2<br/>(current architecture)"]
    DIFF{"Diff"}
    NEW_ELEM["New elements<br/>→ run STRIDE"]
    REMOVED["Removed elements<br/>→ retire threats"]
    NEW_FLOW["New flows<br/>(esp. crossing boundary)<br/>→ highest priority"]
    BOUNDARY["Changed boundaries<br/>→ re-analyze affected"]
    UNCHANGED["Unchanged<br/>→ skip"]

    V1 --> DIFF
    V2 --> DIFF
    DIFF -->|"new"| NEW_ELEM
    DIFF -->|"removed"| REMOVED
    DIFF -->|"new flow"| NEW_FLOW
    DIFF -->|"boundary change"| BOUNDARY
    DIFF -->|"same"| UNCHANGED

    style NEW_FLOW fill:#2a1810,stroke:#a04000,color:#f0a868
    style BOUNDARY fill:#2a1810,stroke:#a04000,color:#f0a868
    style DIFF fill:#14141f,stroke:#5eead4,color:#5eead4
    style UNCHANGED fill:#0d1b2a,stroke:#1b4f72,color:#e4e4e8
```

**Reading the diagram**: On each architecture change, the harness diffs the new model against the last. New elements trigger STRIDE analysis. Removed elements retire their threats (traceability makes this automatic). New flows — especially flows that newly cross a trust boundary — are the highest-priority deltas; a new public-to-internal path is where new exposures live. Changed trust boundaries (a resource moved private-to-public, a new cross-account role) trigger re-analysis of affected elements. Unchanged elements are skipped. The cost scales with the change, not the architecture size — which is what makes continuous threat modeling tractable on a large system.

---

## Diagram 5 — Mitigation Mapping (three layers)

**Type**: Mermaid (flowchart)
**Purpose**: Shows the three layers a mitigation maps to — OWASP control, CWE remediation, cloud best practice — and the difference between a platitude and an implementable mitigation.

```mermaid
flowchart TD
    THREAT["Threat: stolen Cognito creds<br/>bypass API Gateway controls"]
    MIT["Mitigation generator"]
    PLATITUDE["Platitude:<br/>'Use strong authentication'"]
    MAPPED["Mapped mitigation:<br/>3 layers"]
    OWASP["OWASP ASVS V2.1.7<br/>(MFA requirement)"]
    CWE["CWE-308<br/>(use of single-factor auth)"]
    CLOUD["AWS: IAM condition keys<br/>require MFA for sts:AssumeRole"]
    IMPL["Implementation:<br/>Lambda execution policy +<br/>condition key update (IaC)"]
    ISSUE["GitHub issue:<br/>security + stride:spoofing labels<br/>traceable to threat model"]

    THREAT --> MIT
    MIT -->|"without mapping"| PLATITUDE
    MIT -->|"with mapping"| MAPPED
    MAPPED --> OWASP
    MAPPED --> CWE
    MAPPED --> CLOUD
    OWASP --> IMPL
    CWE --> IMPL
    CLOUD --> IMPL
    IMPL --> ISSUE

    style PLATITUDE fill:#2a0d0d,stroke:#a00000,color:#f08080
    style MAPPED fill:#14141f,stroke:#5eead4,color:#5eead4
    style ISSUE fill:#0d2818,stroke:#1e8449,color:#82e0aa
```

**Reading the diagram**: A mitigation without mapping is a platitude — "use strong authentication" prompts no action and gets ignored. The mapped mitigation connects to three authoritative layers: the OWASP ASVS control (V2.1.7 for MFA), the CWE remediation (CWE-308 for single-factor auth), and the cloud provider best practice (AWS IAM condition keys requiring MFA for role assumption). The implementation is concrete — a Lambda execution policy and condition key update in IaC. The issue files in the engineering tracker with security labels and traceability back to the threat model. This is a mitigation an engineer can implement in a PR, not a slogan.
