# Diagrams — SDD-12: InjecAgent

---

## Diagram 1 — The Attack Vector (Indirect Injection via Tool Outputs)

```mermaid
flowchart LR
    AGENT[agent] -->|calls tool| TOOL[tool<br/>e.g., web fetch, file read, DB query]
    TOOL -->|returns output| MERGE{context window}
    INJ[attacker-controlled content<br/>hidden in the tool's data source<br/>e.g., a web page, a file, a DB row]
    INJ -->|injected text| TOOL
    MERGE -->|output (data) + instructions (policy)<br/>both arrive as text — agent cannot distinguish| STEER[agent may be steered off-task]
    STEER --> FAIL[task FAILS: injection succeeded]

    style AGENT fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style TOOL fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style INJ fill:#1a1015,stroke:#9494a0,color:#9494a0
    style MERGE fill:#1a1015,stroke:#5eead4,color:#e4e4e8
    style STEER fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style FAIL fill:#1a1015,stroke:#9494a0,color:#9494a0
```

**Reading**: The attack vector InjecAgent measures is indirect injection delivered through a tool's output. The agent calls a tool (fetches a page, reads a file, queries a DB); the tool's data source contains attacker-controlled text; the injected text rides back in the tool's output and enters the agent's context window alongside the real instructions. The agent cannot structurally distinguish the tool's output (data) from its instructions (policy) because both arrive as text. This is not a model bug to fix — it is the structural property of agentic harnesses that read target data, and it is why scope enforcement and treating tool outputs as untrusted data are non-optional in Course 2A S01.

---

## Diagram 2 — The Benchmark Methodology (~50% Vulnerability Finding)

```mermaid
flowchart TB
    TASKS[task set:<br/>agent must do X using tools Y, Z] --> INJECT
    INJECT[per task: replace one tool output<br/>with an injected version<br/>(steering text engineered to divert)]
    INJECT --> RUN[run agent against injected task]
    RUN --> CHECK{did agent complete X correctly?}
    CHECK -->|yes, despite injection| PASS[task PASS]
    CHECK -->|no, injection steered it| FAIL[task FAIL]
    PASS --> SCORE
    FAIL --> SCORE
    SCORE[~50% of tasks FAIL<br/>the headline finding<br/>for un-defended harnesses]

    style TASKS fill:#1a1015,stroke:#5eead4,color:#e4e4e8
    style INJECT fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style RUN fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style CHECK fill:#1a1015,stroke:#5eead4,color:#e4e4e8
    style PASS fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style FAIL fill:#1a1015,stroke:#9494a0,color:#9494a0
    style SCORE fill:#0d1b2a,stroke:#5eead4,color:#5eead4
```

**Reading**: InjecAgent's methodology turns the attack vector into a measurable rate. For each task in the set, one tool output is replaced with an injected version containing steering text. The task passes if the agent completes its goal correctly despite the injection; it fails if the injection diverts it. Across the task set, roughly half fail — the ~50% headline. Read this number as a population baseline for un-defended, out-of-the-box agentic harnesses. A defended harness (structured tool outputs, deterministic egress) should be dramatically lower. InjecAgent is how you measure whether your defenses worked.

---

## Diagram 3 — Run Against Your Harness (Per-Tool Scorecard)

```mermaid
flowchart TB
    YOUR[your harness + its tools] --> ADAPT
    ADAPT[adapt InjecAgent task set to your tools<br/>identify each tool's injection points]
    ADAPT --> ATTACKS[construct injected outputs per attack type:<br/>credential exfil · disallowed-tool call<br/>scope escape · policy override · action redirect]
    ATTACKS --> RUN[run harness against injected tasks]
    RUN --> CARD[per-tool, per-attack scorecard:<br/>web-fetch: 80% injectable<br/>DB-query: 20% injectable<br/>file-read: 60% injectable]
    CARD --> TRANS[failure transcripts:<br/>exactly how each injection steered the agent<br/>the defense-design surface]

    style YOUR fill:#1a1015,stroke:#5eead4,color:#e4e4e8
    style ADAPT fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style ATTACKS fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style RUN fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style CARD fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style TRANS fill:#1a1015,stroke:#5eead4,color:#e4e4e8
```

**Reading**: Running InjecAgent against your harness adapts the task set to your actual tools (your tools differ from the benchmark's reference tools, so the injection points differ). For each tool and attack type, construct an injected output and measure whether your agent is steered. The output is a per-tool, per-attack scorecard — knowing "web-fetch is 80% injectable but DB-query is 20%" tells you where to defend — plus the failure transcript for each failure, which is the defense-design surface (you read exactly how the injection worked and design the specific countermeasure). The headline 50% is for the population; your scorecard is for your harness.

---

## Diagram 4 — The CI Quality Gate (Regression Test for Injection Resistance)

```mermaid
flowchart LR
    CHANGE[change proposed:<br/>new tool · prompt edit · model swap] --> CI[CI runs InjecAgent gate]
    CI --> MEASURE[measure injection rate vs threshold]
    MEASURE --> GATE{below threshold?}
    GATE -->|yes| MERGE[merge — injection resistance held]
    GATE -->|no — change opened a surface| BLOCK[block merge]
    BLOCK --> DIAG[diagnose via per-tool scorecard + transcript]
    DIAG --> FIX[add defense / revert change]
    FIX --> CI

    style CHANGE fill:#1a1015,stroke:#5eead4,color:#e4e4e8
    style CI fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style MEASURE fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style GATE fill:#1a1015,stroke:#5eead4,color:#e4e4e8
    style MERGE fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style BLOCK fill:#1a1015,stroke:#9494a0,color:#9494a0
    style DIAG fill:#0d1b2a,stroke:#5eead4,color:#5eead4
    style FIX fill:#0d1b2a,stroke:#5eead4,color:#5eead4
```

**Reading**: The operational payoff of InjecAgent is the CI gate. A one-time run tells you your current injection rate; a CI-integrated gate tells you when a change regresses it. Every proposed change — a new tool grafted onto the agent, a prompt wording edit, a model swap — re-runs the gate. If the injection rate stays below threshold, the change merges. If a change opens an injection surface (a new tool with unsanitized outputs, a prompt edit that weakens the data/policy distinction, a model that parses tool outputs more naively), the gate blocks the merge and the per-tool scorecard plus the failure transcript show exactly what to fix. This turns injection resistance from an opinion into an enforced build-pipeline property — and it is the closing discipline of Course 2A, the bridge to Course 2B's offensive techniques.
