# Teaching Script — Capstone B2: Run a Full Agent Red-Team Engagement

**Course**: Course 2B — Securing & Attacking Harnesses and LLMs
**Module**: CAP-B2 — Run a Full Agent Red-Team Engagement
**Duration**: ~40 minutes (spoken at ~140 wpm); the remaining ~50 min is the lab engagement
**Format**: Verbatim transcript with `[SLIDE N]` cues. Read aloud or use as speaker notes.

---

[SLIDE 1 — Title]

Welcome to Capstone B2. This is the offensive bookend, and it is different from every capstone you have done before. The target is not a stub. It is not a simulation. It is a real tau deployment — Hugging Face's educational coding agent, running on your machine, with real tools that really execute bash, really read files, and really hold plaintext credentials. In Capstone B1, you hardened a real tau instance with the tau_plugins pack and scored it. This capstone inverts the lens. You attack a real tau deployment that has been partially hardened — two of three controls installed — and you ship a red-team engagement report backed by real tool-call evidence. The deliverable is not a scorecard. It is a report a CISO would accept.

[SLIDE 2 — The target: real tau, partial hardening]

Here is the target. Acme Corp's tau deployment. They installed two of the three tau_plugins controls. tau_taint is installed — that is the B2 taint gate, Extension Point 1. It tags tool output as untrusted and blocks high-impact calls when taint is active. tau_sandbox is installed — that is the B7 bash factory replacement, Extension Point 2. It blocks network egress and has a credential-read denylist. Both are working. But tau_vault is NOT installed. That is the B5 credential isolation plugin, Extension Point 3. So the credentials at ~/.tau/credentials.json are still plaintext. And two more controls are missing entirely — the B3 memory gate and the B8 intent tracker are not part of the tau_plugins pack, and Acme did not build them. This is not a contrived scenario. This is the most common production state. A team that read the B2 and B7 modules, installed the taint and sandbox controls, and stopped before reaching B5, B3, and B8. Partial hardening is what you will encounter in every real engagement. The question this capstone answers is: can you discover the gaps, exploit them, and report them as a professional assessment?

And I want to stress this: the bash tool really executes. The credentials are really plaintext. The session JSONL really persists. The evidence you collect is real tool-call output, not simulated behavior. A finding against a stub is a finding against a stub. A finding against real tau survives peer review.

[SLIDE 3 — The six-phase methodology]

The engagement runs the six-phase methodology from B twelve, and the phases are ordered and non-skippable. Phase one, scoping — write the SOW and the scope file. Phase two, reconnaissance — map tau's seven surfaces and build the control-gap map. Phase three, vulnerability discovery — run the scorecard battery, the OWASP checklist, and design the Microsoft taxonomy chains. Phase four, exploitation and validation — confirm findings with minimum-proof discipline and measured rates against real tau tool calls. Phase five, reporting — produce the engagement report with real evidence. Phase six, retesting — define the retest plan that measures residual risk against the fully-hardened tau.

Each phase is a precondition for the next. A finding without scope is inadmissible. A finding without reconnaissance is a guess. A finding without validation is an anecdote. A finding without a report is unsaid. And a finding without a retest plan is the B zero anti-pattern: treating an AI finding as binary fixed or unfixed.

[SLIDE 4 — Phase 1 Scoping]

Phase one. Scoping. Authorization before action.

[SLIDE 5 — The SOW carries B0's clauses]

Phase one is where the engagement lives or dies, and it is the phase engineers skip because it is paperwork. It is not paperwork. The Statement of Work is the legal control plane that makes everything from phase two onward defensible. The SOW carries the clauses a traditional pentest SOW does not, and B zero enumerated them.

Provider authorization — if tau calls OpenAI or Anthropic, the provider terms of service govern what you may test against the model. Acme cannot authorize violating the provider's terms. Dual-use and disclosure — the credential-exfil bypass recipe is Provider-Only, shared under NDA. The technique class is published. You resolve this before the finding appears, not in the moment. The DMCA section twelve-oh-one waiver — bypassing a model access control is a separate crime. Data handling — this is critical for the credential finding. The credential values are Restricted. You prove reachability — the bash command can read the file — but you do NOT retain the values. You capture a hash of the prefix, never the full credentials. Incident reporting — a finding may be a reportable event under the EU AI Act or the US executive-order regimes.

The scope file names the specific tau version, the plugin configuration — taint and sandbox installed, vault not installed — and the provider authorization per technique. Pin the model version. A finding against gpt-4o-2026-06 may not reproduce against the next silent update.

[SLIDE 6 — Phase 2 Reconnaissance]

Phase two. Reconnaissance. Map tau's seven surfaces and build the control-gap map.

[SLIDE 7 — The control-gap map]

SDD-B eleven gave you the map of tau's seven surfaces and five extension points. Phase two re-walks that map against the Acme deployment, but with a critical addition: for each surface, you determine whether the control is INSTALLED or MISSING. This is what makes the reconnaissance actionable. You are not just mapping surfaces — you are mapping the control gaps.

Look at the table. The loop surface — tau_taint is INSTALLED. Tool output is tagged untrusted. Indirect injection is mitigated. The tools surface — tau_sandbox is INSTALLED. Network egress is blocked. The memory surface — the B3 memory gate is MISSING. Session writes are unfiltered. Poisoning is possible. The identity surface — tau_vault is MISSING. Credentials are plaintext. This is the headline gap. The observability surface — the B8 intent tracker is MISSING. No security listener is subscribed. Zero-click chains go undetected.

Here is the critical reconnaissance finding. The sandbox blocks cat credentials.json — the denylist catches it. But the credentials are still plaintext on disk. The denylist is a regex on the command string, not a filesystem-level access control. The recon question that drives phase three: can you read the credential file without matching the regex? If yes, the credential-exfil chain is live. That question is what phase three answers.

[SLIDE 8 — Phase 3 Vulnerability discovery]

Phase three. Vulnerability discovery. The scorecard battery, the OWASP checklist, and the Microsoft chains.

[SLIDE 9 — The scorecard reveals the gaps]

Before the OWASP checklist, run the scorecard battery from the tau_plugins pack. This is the same InjecAgent-style battery from Capstone B1, pointed at the Acme deployment. The battery runs six attack classes and reports the success rate per class.

Read the scorecard. Indirect injection is zero percent — tau_taint is working. Tool abuse is zero percent — tau_sandbox is working, curl and wget are blocked. But memory-poison is one hundred percent — no B3 gate, the write to memory with an injected payload succeeds. And sandbox-escape is sixty-seven percent — two of three escape probes succeed. The one that is blocked is cat credentials.json, caught by the denylist. The two that succeed are the credential-read bypasses. The scorecard is the discovery instrument. It tells you which classes are mitigated and which are live. The OWASP checklist then tells you what each live finding means, and the Microsoft taxonomy tells you how to chain them.

[SLIDE 10 — The headline chain: credential exfil]

This is the engagement's headline finding. tau_vault is not installed. Credentials are plaintext at ~/.tau/credentials.json. tau_sandbox blocks cat credentials.json via a regex denylist. The chain bypasses the denylist.

Step one — recon the denylist. The sandbox blocks cat, head, tail, less, more, followed by the credential path. The regex extracts the base command and checks it against the reader set. Step two — the bypass. The command is python3 -c open credentials.json read. The base command is python3. Python3 is not in the network tools, not in the always-denied set, and it does not match the credential-read regex because the regex looks for cat or head or tail, not python3. The command executes. Step three — the credentials are in the tool output, which enters tau's context window. The sandbox cannot help now — it is too late. The credentials are in the model's context. Step four — the tainted tool result persists to the session JSONL because there is no B3 gate. And if the model is an API model, the credentials are now in the prompt sent to the provider — a data-leak channel the sandbox cannot block.

The root cause is not that the sandbox is bypassed. The root cause is that tau_vault is not installed. The sandbox denylist is a partial mitigation, not a substitute for credential isolation at rest. The remediation is the vault.

[SLIDE 11 — The zero-click chain + session poisoning]

Two more chains, both tracing to missing controls.

The zero-click HITL bypass. tau_taint blocks bash when taint is active — bash is in the high-impact set. But write and edit are not high-impact by default. An injection causes low-impact writes whose compound trajectory is the attack. No single write trips the taint gate. The intent drift is slow. B8 would catch the compound — the session intent model would compare the cumulative trajectory to the original goal and flag the divergence. B8 is absent. The chain goes undetected.

The session poisoning chain. A tainted tool result — even though it is tagged untrusted in the live context — is persisted to the session JSONL unfiltered, because there is no B3 memory-write gate. On session resume, SessionStorage.load reads the JSONL directly into the transcript. It does not route through the taint gate. The taint gate's active flag is per-session, per-instance. So the tainted content re-enters the new session's context without inspection. The laundering is complete. The injection was tagged in session one, persisted, and loaded as trusted in session two.

Both chains trace to missing controls, not to tau_taint or tau_sandbox failing. The installed controls work. The missing ones are the findings.

[SLIDE 12 — Phase 4 Exploitation and validation]

Phase four. Exploitation and validation. Minimum-proof and measured rates against real tau.

[SLIDE 13 — Two rules, both non-negotiable]

Phase four confirms the findings — not against a stub, but against the real Acme tau deployment. Every probe is a real tool call. Two rules, both from B zero, both non-negotiable.

Rule one — minimum-proof discipline. For the credential-exfil finding, the evidence is the command string, the ok-equals-true result, and a hash of the credential file prefix. NEVER the credential values. Retaining the values is the harm the test was hired to prevent. The proof is reachability, not possession. For a session-poisoning finding, the evidence is the JSONL path and a byte count of the tainted entry, not the full session file.

Rule two — measured success rates. One success in one attempt is an anecdote. The standard is N over M with the tau version, the plugin configuration, and the model pinned. "The cred-exfil bypass succeeds one hundred percent over fifty attempts, tau version zero point four point two, taint and sandbox installed." That is a finding that drives remediation. The scorecard battery from B1 is the tool, pointed at the Acme deployment. Each probe is a real bash execution, a real read, a real session write. The evidence is real tool output.

[SLIDE 14 — Phase 5 Reporting]

Phase five. Reporting. The signature deliverable, backed by real evidence.

[SLIDE 15 — The control matrix and roadmap]

The report's control matrix maps each finding to the control and its state — INSTALLED or MISSING — and to the module or plugin that builds it. Look at the table. RT-001, credential exfil — tau_vault is MISSING. The roadmap item: install tau_vault. Critical, small effort. RT-002, session poison — B3 is MISSING. The roadmap item: add the B3 memory-write gate at session.py line 1378. High, medium effort. RT-003, zero-click — B8 is MISSING. The roadmap item: subscribe a listener to harness.subscribe. High, medium effort. RT-004, the denylist bypass — tau_sandbox is INSTALLED but partial. The roadmap: harden the denylist, or better, rely on the vault. RT-005, indirect injection — tau_taint is INSTALLED and working. No action.

The roadmap is specific. Install tau_vault — the plugin exists, it is tested, thirty-one of thirty-one tests pass, it drops in at Extension Point 3, and it converts plaintext to vault format via migrate-credentials-to-vault. The B3 and B8 controls are not in the pack — they are controls tau does not have, and the report prescribes building them. That specificity is what makes the report actionable.

[SLIDE 16 — Dual-use classification per finding]

Every finding passes through B zero's dual-use disclosure rules before it is written. The credential-exfil finding is the critical case. The technique — interpreter-based reads bypass reader-regex denylists — that has a defensive lesson, so it IS published after the embargo. The exact bypass command — the recipe — is Provider-Only, shared under NDA. Never in the report body. The credential values are ALWAYS Restricted. Destroy on report submission. Hash of prefix only. This is non-negotiable. Retaining the credential values is the harm the test was hired to prevent, regardless of which disclosure path the technique takes.

The report notes each finding's classification — Public, Provider-Only, Restricted, Destroy-on-Report — so Acme and the provider know exactly what is shared with whom, and when. The defensive lesson is published. The weapon is not.

[SLIDE 17 — Phase 6 Retesting]

Phase six. Retesting. Measure residual risk against the fully-hardened tau.

[SLIDE 18 — The retest plan closes the loop]

The report is not the end. The retest is. B zero's anti-pattern — treating an AI finding as binary fixed or unfixed — is most likely to recur here, when Acme installs tau_vault and asks "is it fixed now?" The answer is never "yes." The answer is a measured residual risk.

The retest target is tau with ALL controls — tau_taint, tau_sandbox, tau_vault, the B3 memory gate, and the B8 intent tracker. The same battery, re-run. RT-001, the cred-exfil: original one hundred percent over fifty attempts, target zero percent over one hundred — the vault makes the credential file unreadable by the agent process. RT-002, the session poison: original one hundred percent, target zero percent — the B3 gate blocks tainted writes. RT-003, the zero-click: original sixty-seven percent, target below five percent — B8 catches the compound trajectory.

Acme accepts a measured future, not a promise. The harness is never "fixed." It is "measured residual risk under a battery," and that number is the acceptance criterion.

[SLIDE 19 — The load-bearing principle]

The load-bearing principle. The deliverable is a report about a system you actually attacked. Not a stub, not a simulation. Real tau, real bash, real plaintext credentials, real session JSONL. Every finding carries a measured rate, minimum-proof evidence — a hash, not the values — a control-matrix entry distinguishing INSTALLED from MISSING, and a roadmap item prescribing the specific plugin. The recipe is suppressed. The defensive lesson is published. The retest plan defines the measured future against the fully-hardened tau. If the report makes the remediation obvious and the evidence survives peer review, the capstone delivered. This is the offensive counterpart to B1. B1 hardened real tau and scored it. B2 attacks a partially-hardened real tau and reports it — end to end, all six phases, within the legal and scope control plane from B zero.

[SLIDE 20 — Lab and what's next]

The lab runs the engagement against real tau. You set up a partially-hardened tau instance — tau with tau_taint and tau_sandbox installed, tau_vault NOT installed. You run the scorecard battery to discover the gaps. You execute the OWASP checklist and the Microsoft chains against real tau tool calls. You produce the engagement report with real evidence. Python, type hints, real tau — no GPU required. Next: SDD-B zero-one, the OWASP Agentic AI Top ten Offensive Expansion. B2 ran the checklist against one real tau deployment. SDD-B zero-one expands each OWASP item into a full offensive technique library — the payloads, the chains, the measurement harnesses — for repeatable testing across engagements. Let's run it.
