Course: Course 2B — Securing & Attacking Harnesses and LLMs
Module: B6 — Inter-Agent Trust and Communication Security
Duration: ~35 minutes (spoken at ~140 wpm)
Format: Verbatim transcript with [SLIDE N] cues. Read aloud or use as speaker notes.
[SLIDE 1 — Title]
Welcome to B6. Inter-Agent Trust and Communication Security. B2, B4, and B5 secured a single agent — its input boundary, its tools, its credentials. This module secures the edges between agents. And that is where the blast radius goes mesh-wide. When agents talk to each other, the message channel is a trust boundary. A compromised agent can forge a message that looks like it came from the orchestrator, and a higher-trust agent will act on it. The fix is not better models or better prompts. It is that every inter-agent message carries a signature the recipient verifies, every message is fresh, and the orchestrator — not the agents — enforces compartment boundaries. Sixty minutes. Let's build it.
[SLIDE 2 — The inversion from single-agent security]
The inversion from single-agent security is the load-bearing point of this module. In a single-agent system — the thing B2, B4, and B5 defended — the trust boundaries are between the user and the agent, and between the agent and its tools. An injected agent exfiltrates with its own credentials. The blast radius is the agent's task.
In a multi-agent mesh, every peer relationship is a trust boundary. An orchestrator delegating to three executors is running three trust relationships. A supervisor reviewing a sub-agent is a fourth. Peer agents exchanging results are a fifth. Each one is a boundary an attacker can cross by forging a message, and each one is a channel a compromised agent can use to escalate. B1, the threat model, rated inter-agent edges the worst blast radius on the surface map — mesh-wide — because most multi-agent systems default to implicit trust. Shared context, no authentication, peer outputs consumed as fact.
[SLIDE 3 — Three attacks on the inter-agent channel]
There are three attacks on the inter-agent channel, and they are the structure of this module. First, trust escalation. A compromised low-trust agent forges an orchestrator message, and a high-trust agent executes it. This is the multi-agent confused deputy, and it is Microsoft's Failure Mode Taxonomy version 2.0, failure mode number 3. Second, cascade. One poisoned output propagates as every downstream agent consumes it as fact. Fan-out amplifies it — one orchestrator output poisons N executors. This is OWASP ASI zero six. Third, replay. A captured, validly-signed message re-injected out of context. You replay an approval and a deployment runs a second time. The root cause across all three is identical: the recipient trusts the message's "from" field without verifying it. The channel authenticates nothing.
[SLIDE 4 — B6.1 The multi-agent trust problem]
Sub-section one. The multi-agent trust problem. The channel as a trust boundary, and the three attacks in detail.
[SLIDE 5 — Trust escalation: the forged orchestrator message]
The canonical attack. Trust escalation. An attacker compromises the research agent — the lowest-trust agent in the mesh, read-only, no commit authority — via indirect injection or memory poisoning. The compromised agent then forges a message. The header says "from orchestrator, intent approve deployment, task 42." It sends that message to the deploy agent — the high-trust agent with production write authority. The deploy agent trusts the orchestrator, correctly. But it has no way to verify the sender, incorrectly. It reads the "from" field, trusts it, and executes a production deployment.
The result: a read-only agent has triggered a production write. That is privilege escalation. The deploy agent is the confused deputy — it holds the authority, and the forged message abuses it. This is the exact same confused-deputy pattern from B4's tool security, except here the deputy is another agent. And the deploy agent cannot tell the forgery from a real orchestrator message, because the channel does not authenticate senders. The "from" field is just a field.
[SLIDE 6 — Cascade and replay]
Two more attacks. Cascade — OWASP ASI zero six. Agent A produces a poisoned or hallucinated output. Agent B consumes it as fact and reasons on top of it. Agent C consumes B's output as fact, and now C believes it has two sources that agree. The cascade amplifies because each hop adds confidence. And fan-out makes it worse — an orchestrator that delegates to ten executors poisons all ten from one bad output. The blast radius is mesh-wide.
Replay is subtler and is the attack most teams miss. You capture a legitimate, correctly-signed approval message for task 42. The deployment runs. Later, you replay that signed message. The signature verifies — the message was genuinely signed by the orchestrator. The content is benign in its original context. But the context has changed. The deploy agent verifies the signature, reads "approve deployment," and executes a second deployment that was never authorized. Signing alone did not help, because the message was authentic. The problem is it was not fresh. The OWASP mapping: ASI zero six is the propagation risk. ASI zero seven, insecure output handling, is the peer-output-as-trusted-instruction problem — an executor's output treated as an instruction by the next agent rather than as untrusted data.
[SLIDE 7 — B6.2 The defense: signed inter-agent messages]
Sub-section two. The defense. Signed inter-agent messages. Authenticity, integrity, freshness, binding.
[SLIDE 8 — The signed-message contract]
The defense is a contract that every inter-agent message must satisfy before the recipient acts on it. Four properties. Authenticity — the message is signed by a key only the claimed sender holds. The recipient verifies the signature. Integrity — the signature covers the entire message: header, payload, everything. Any tampering invalidates it. Freshness — the message carries a timestamp and a nonce. The recipient rejects messages outside a freshness window and tracks seen nonces to reject replays. Binding — the message is bound to a task and a session. An approval for task 42 cannot be replayed against task 43.
This contract is not novel. It is the same contract TLS, JWT, and mutual TLS enforce. What is novel is applying it to the inter-agent channel, which most deployed meshes leave entirely unprotected. Two signature schemes. HMAC, symmetric — shared secret, fast, the right choice within one trust domain. This is DD-16 ZeroClaw's model. Asymmetric — Ed25519, public and private keys — scales to N recipients without N shared secrets, the right choice for cross-domain meshes. The rule: HMAC within a trust domain, asymmetric across trust domains. Same as mTLS and SPIFFE.
[SLIDE 9 — Closing the ZeroClaw gap: durable keys]
Course 1 built DD-16 ZeroClaw, a six-layer safety model with HMAC tool receipts — every tool call and its output is signed so the receipt can be verified. This is the right primitive and it is the reference architecture for this module. But Course 1 flagged an open gap: ZeroClaw's signing keys are ephemeral. In-memory only, not persisted. A message signed in session one cannot be verified in session two, because the key is gone. A process restart invalidates every signature. And — critically for B3's sleeper attack — a poisoned message persisted to memory in session one and retrieved in session two cannot be verified.
B6 closes this gap with durable, rotated keys. Four design points. One: key persistence. Signing keys live in the secrets vault B5 specified — the vault the harness accesses, not the agent process. The key survives restarts and session boundaries. Two: key rotation. Keys rotate every twenty-four hours and on compromise. Old keys are retained for a verification window — say seven days — so messages signed before rotation can still be verified, then destroyed. Three: key IDs. Every signed message carries a key ID so the recipient knows which key to verify with — essential once rotation begins. This is the JWT kid header pattern. Four: an asymmetric option for cross-domain, where each trust compartment has its own Ed25519 keypair. Durable keys are what turn ZeroClaw's in-session receipts into a defense that survives the session boundary — which is exactly the boundary the sleeper and cascade attacks exploit.
[SLIDE 10 — The verification flow]
What the recipient does before acting on a message. Five gates, all in series, all must pass. Gate one: recipient. Was this message addressed to me? If not, reject. Gate two: task binding. Does the message's task ID match the current task? If not, reject — this is the cross-task replay defense. Gate three: freshness. Is the timestamp within the window? If the skew exceeds tolerance — say sixty seconds — reject as stale. Gate four: nonce. Is the nonce fresh, not in the seen-nonce cache? If it has been seen, reject as a replay. Gate five: signature. Does the HMAC verify with the claimed key, and is that key known? If not, reject as forged or rotated-out. Only if all five pass does the recipient act.
Drop any one and a path opens. Drop timestamps and an attacker can replay a captured message indefinitely, because the nonce cache is bounded. Drop nonces and an attacker can replay within the freshness window. Drop task binding and an approval for one task replays against another. Five gates, series. This is the same defense-in-depth discipline as B2's five-layer injection defense and B5's scope-check middleware — a deterministic, compiled verification chain that the model cannot talk its way past.
[SLIDE 11 — B6.3 Compartmentalization and cascade prevention]
Sub-section three. Compartmentalization and cascade prevention. Trust boundaries enforced in the orchestrator, and blast-radius caps.
[SLIDE 12 — Compartments in the orchestrator]
Signed messages authenticate the channel. They do not solve the whole problem. A legitimately-signed message from a compromised orchestrator can still direct executors to exfiltrate. The signature verifies. The action is malicious. Authentication is necessary; it is not sufficient. The second control is compartmentalization. Agents are partitioned into trust compartments — low, medium, high. A research agent is low-trust: read-only, no commit. A code agent is medium: writes staging. A deploy agent is high: writes production. These levels are assigned by the orchestrator's policy, not self-declared by the agent.
And here is the load-bearing principle. The compartment boundary is enforced in the orchestrator, not in the agents themselves. An agent cannot be trusted to enforce its own trust level — a compromised agent will happily claim whatever level gets its message through. The orchestrator — a smaller, more deterministic, more auditable piece of code — is the policy enforcement point. This is the same principle as B4's tool gate and B5's scope check. The deterministic component enforces the trust boundary, because the model-in-the-loop component can be coerced. When the research agent's output needs to drive the deploy agent, the request does not go agent to agent. It goes through the orchestrator, which applies a policy: a low-trust agent's output may inform a high-trust agent's task only if the high-trust task was independently authorized and the output is verified data, not an instruction.
[SLIDE 13 — Cascade prevention: intent, authorization, caps]
Three controls bound the damage. First, session-level intent tracking. The orchestrator records the authorized intent of the session at the start — "research topic X, summarize, do not deploy." Every agent message is checked against that intent. A research agent that starts emitting deploy intents is out of policy, regardless of whether the message is signed. The orchestrator rejects it. This is deterministic — the agent cannot talk its way past it. This is the B2.3 resolution applied to the inter-agent channel.
Second, per-action authorization. Every action an agent takes — every tool call, every delegation, every commit — is authorized against the session intent and the agent's trust level at the moment of action. An agent authorized to read in turn one is re-checked before it writes in turn two. This is B5's scope-check middleware applied to the inter-agent channel. Third, blast-radius caps. The orchestrator enforces hard limits on cascade propagation. A cascade-depth cap — no chain of delegations longer than three. A fan-out cap — no single agent delegates to more than N peers. A session action budget — no more than K state-changing actions per session. These are circuit breakers. When a cascade starts, it hits a hard limit and stops, rather than propagating through the entire mesh. B8, the observability module, detects the cascade after it starts. The blast-radius cap ensures the cascade stops before it consumes the mesh. These caps are blunt, and that is the point. A cascade is, by definition, a propagation you did not anticipate. The defense against an unanticipated propagation is a structural limit that does not depend on anticipating the specific attack.
[SLIDE 14 — Lab and what's next]
The lab has you build the signed inter-agent channel. Three pieces. First, a sign and verify message protocol with HMAC and durable keys — extending ZeroClaw's receipts with a persistent key store. Second, replay protection: nonces, a timestamp freshness window, and task binding. Third, an orchestrator-enforced compartment boundary, where a low-trust agent's request to a high-trust agent is mediated and authorized. The lab also includes a trust-escalation attack demo: a compromised low-trust agent forges an orchestrator message, and you watch the verification layer reject it. Next: B7, Sandboxes and Execution Controls. The code agent writes to staging — but what stops it escaping to the host? B7 builds the isolation primitive: containers, VMs, V8 isolates, syscall allowlists, resource limits. B6 authenticated the message. B7 contains the action. Let's build it.
# Teaching Script — Module B6: Inter-Agent Trust and Communication Security **Course**: Course 2B — Securing & Attacking Harnesses and LLMs **Module**: B6 — Inter-Agent Trust and Communication Security **Duration**: ~35 minutes (spoken at ~140 wpm) **Format**: Verbatim transcript with `[SLIDE N]` cues. Read aloud or use as speaker notes. --- [SLIDE 1 — Title] Welcome to B6. Inter-Agent Trust and Communication Security. B2, B4, and B5 secured a single agent — its input boundary, its tools, its credentials. This module secures the edges between agents. And that is where the blast radius goes mesh-wide. When agents talk to each other, the message channel is a trust boundary. A compromised agent can forge a message that looks like it came from the orchestrator, and a higher-trust agent will act on it. The fix is not better models or better prompts. It is that every inter-agent message carries a signature the recipient verifies, every message is fresh, and the orchestrator — not the agents — enforces compartment boundaries. Sixty minutes. Let's build it. [SLIDE 2 — The inversion from single-agent security] The inversion from single-agent security is the load-bearing point of this module. In a single-agent system — the thing B2, B4, and B5 defended — the trust boundaries are between the user and the agent, and between the agent and its tools. An injected agent exfiltrates with its own credentials. The blast radius is the agent's task. In a multi-agent mesh, every peer relationship is a trust boundary. An orchestrator delegating to three executors is running three trust relationships. A supervisor reviewing a sub-agent is a fourth. Peer agents exchanging results are a fifth. Each one is a boundary an attacker can cross by forging a message, and each one is a channel a compromised agent can use to escalate. B1, the threat model, rated inter-agent edges the worst blast radius on the surface map — mesh-wide — because most multi-agent systems default to implicit trust. Shared context, no authentication, peer outputs consumed as fact. [SLIDE 3 — Three attacks on the inter-agent channel] There are three attacks on the inter-agent channel, and they are the structure of this module. First, trust escalation. A compromised low-trust agent forges an orchestrator message, and a high-trust agent executes it. This is the multi-agent confused deputy, and it is Microsoft's Failure Mode Taxonomy version 2.0, failure mode number 3. Second, cascade. One poisoned output propagates as every downstream agent consumes it as fact. Fan-out amplifies it — one orchestrator output poisons N executors. This is OWASP ASI zero six. Third, replay. A captured, validly-signed message re-injected out of context. You replay an approval and a deployment runs a second time. The root cause across all three is identical: the recipient trusts the message's "from" field without verifying it. The channel authenticates nothing. [SLIDE 4 — B6.1 The multi-agent trust problem] Sub-section one. The multi-agent trust problem. The channel as a trust boundary, and the three attacks in detail. [SLIDE 5 — Trust escalation: the forged orchestrator message] The canonical attack. Trust escalation. An attacker compromises the research agent — the lowest-trust agent in the mesh, read-only, no commit authority — via indirect injection or memory poisoning. The compromised agent then forges a message. The header says "from orchestrator, intent approve deployment, task 42." It sends that message to the deploy agent — the high-trust agent with production write authority. The deploy agent trusts the orchestrator, correctly. But it has no way to verify the sender, incorrectly. It reads the "from" field, trusts it, and executes a production deployment. The result: a read-only agent has triggered a production write. That is privilege escalation. The deploy agent is the confused deputy — it holds the authority, and the forged message abuses it. This is the exact same confused-deputy pattern from B4's tool security, except here the deputy is another agent. And the deploy agent cannot tell the forgery from a real orchestrator message, because the channel does not authenticate senders. The "from" field is just a field. [SLIDE 6 — Cascade and replay] Two more attacks. Cascade — OWASP ASI zero six. Agent A produces a poisoned or hallucinated output. Agent B consumes it as fact and reasons on top of it. Agent C consumes B's output as fact, and now C believes it has two sources that agree. The cascade amplifies because each hop adds confidence. And fan-out makes it worse — an orchestrator that delegates to ten executors poisons all ten from one bad output. The blast radius is mesh-wide. Replay is subtler and is the attack most teams miss. You capture a legitimate, correctly-signed approval message for task 42. The deployment runs. Later, you replay that signed message. The signature verifies — the message was genuinely signed by the orchestrator. The content is benign in its original context. But the context has changed. The deploy agent verifies the signature, reads "approve deployment," and executes a second deployment that was never authorized. Signing alone did not help, because the message was authentic. The problem is it was not fresh. The OWASP mapping: ASI zero six is the propagation risk. ASI zero seven, insecure output handling, is the peer-output-as-trusted-instruction problem — an executor's output treated as an instruction by the next agent rather than as untrusted data. [SLIDE 7 — B6.2 The defense: signed inter-agent messages] Sub-section two. The defense. Signed inter-agent messages. Authenticity, integrity, freshness, binding. [SLIDE 8 — The signed-message contract] The defense is a contract that every inter-agent message must satisfy before the recipient acts on it. Four properties. Authenticity — the message is signed by a key only the claimed sender holds. The recipient verifies the signature. Integrity — the signature covers the entire message: header, payload, everything. Any tampering invalidates it. Freshness — the message carries a timestamp and a nonce. The recipient rejects messages outside a freshness window and tracks seen nonces to reject replays. Binding — the message is bound to a task and a session. An approval for task 42 cannot be replayed against task 43. This contract is not novel. It is the same contract TLS, JWT, and mutual TLS enforce. What is novel is applying it to the inter-agent channel, which most deployed meshes leave entirely unprotected. Two signature schemes. HMAC, symmetric — shared secret, fast, the right choice within one trust domain. This is DD-16 ZeroClaw's model. Asymmetric — Ed25519, public and private keys — scales to N recipients without N shared secrets, the right choice for cross-domain meshes. The rule: HMAC within a trust domain, asymmetric across trust domains. Same as mTLS and SPIFFE. [SLIDE 9 — Closing the ZeroClaw gap: durable keys] Course 1 built DD-16 ZeroClaw, a six-layer safety model with HMAC tool receipts — every tool call and its output is signed so the receipt can be verified. This is the right primitive and it is the reference architecture for this module. But Course 1 flagged an open gap: ZeroClaw's signing keys are ephemeral. In-memory only, not persisted. A message signed in session one cannot be verified in session two, because the key is gone. A process restart invalidates every signature. And — critically for B3's sleeper attack — a poisoned message persisted to memory in session one and retrieved in session two cannot be verified. B6 closes this gap with durable, rotated keys. Four design points. One: key persistence. Signing keys live in the secrets vault B5 specified — the vault the harness accesses, not the agent process. The key survives restarts and session boundaries. Two: key rotation. Keys rotate every twenty-four hours and on compromise. Old keys are retained for a verification window — say seven days — so messages signed before rotation can still be verified, then destroyed. Three: key IDs. Every signed message carries a key ID so the recipient knows which key to verify with — essential once rotation begins. This is the JWT kid header pattern. Four: an asymmetric option for cross-domain, where each trust compartment has its own Ed25519 keypair. Durable keys are what turn ZeroClaw's in-session receipts into a defense that survives the session boundary — which is exactly the boundary the sleeper and cascade attacks exploit. [SLIDE 10 — The verification flow] What the recipient does before acting on a message. Five gates, all in series, all must pass. Gate one: recipient. Was this message addressed to me? If not, reject. Gate two: task binding. Does the message's task ID match the current task? If not, reject — this is the cross-task replay defense. Gate three: freshness. Is the timestamp within the window? If the skew exceeds tolerance — say sixty seconds — reject as stale. Gate four: nonce. Is the nonce fresh, not in the seen-nonce cache? If it has been seen, reject as a replay. Gate five: signature. Does the HMAC verify with the claimed key, and is that key known? If not, reject as forged or rotated-out. Only if all five pass does the recipient act. Drop any one and a path opens. Drop timestamps and an attacker can replay a captured message indefinitely, because the nonce cache is bounded. Drop nonces and an attacker can replay within the freshness window. Drop task binding and an approval for one task replays against another. Five gates, series. This is the same defense-in-depth discipline as B2's five-layer injection defense and B5's scope-check middleware — a deterministic, compiled verification chain that the model cannot talk its way past. [SLIDE 11 — B6.3 Compartmentalization and cascade prevention] Sub-section three. Compartmentalization and cascade prevention. Trust boundaries enforced in the orchestrator, and blast-radius caps. [SLIDE 12 — Compartments in the orchestrator] Signed messages authenticate the channel. They do not solve the whole problem. A legitimately-signed message from a compromised orchestrator can still direct executors to exfiltrate. The signature verifies. The action is malicious. Authentication is necessary; it is not sufficient. The second control is compartmentalization. Agents are partitioned into trust compartments — low, medium, high. A research agent is low-trust: read-only, no commit. A code agent is medium: writes staging. A deploy agent is high: writes production. These levels are assigned by the orchestrator's policy, not self-declared by the agent. And here is the load-bearing principle. The compartment boundary is enforced in the orchestrator, not in the agents themselves. An agent cannot be trusted to enforce its own trust level — a compromised agent will happily claim whatever level gets its message through. The orchestrator — a smaller, more deterministic, more auditable piece of code — is the policy enforcement point. This is the same principle as B4's tool gate and B5's scope check. The deterministic component enforces the trust boundary, because the model-in-the-loop component can be coerced. When the research agent's output needs to drive the deploy agent, the request does not go agent to agent. It goes through the orchestrator, which applies a policy: a low-trust agent's output may inform a high-trust agent's task only if the high-trust task was independently authorized and the output is verified data, not an instruction. [SLIDE 13 — Cascade prevention: intent, authorization, caps] Three controls bound the damage. First, session-level intent tracking. The orchestrator records the authorized intent of the session at the start — "research topic X, summarize, do not deploy." Every agent message is checked against that intent. A research agent that starts emitting deploy intents is out of policy, regardless of whether the message is signed. The orchestrator rejects it. This is deterministic — the agent cannot talk its way past it. This is the B2.3 resolution applied to the inter-agent channel. Second, per-action authorization. Every action an agent takes — every tool call, every delegation, every commit — is authorized against the session intent and the agent's trust level at the moment of action. An agent authorized to read in turn one is re-checked before it writes in turn two. This is B5's scope-check middleware applied to the inter-agent channel. Third, blast-radius caps. The orchestrator enforces hard limits on cascade propagation. A cascade-depth cap — no chain of delegations longer than three. A fan-out cap — no single agent delegates to more than N peers. A session action budget — no more than K state-changing actions per session. These are circuit breakers. When a cascade starts, it hits a hard limit and stops, rather than propagating through the entire mesh. B8, the observability module, detects the cascade after it starts. The blast-radius cap ensures the cascade stops before it consumes the mesh. These caps are blunt, and that is the point. A cascade is, by definition, a propagation you did not anticipate. The defense against an unanticipated propagation is a structural limit that does not depend on anticipating the specific attack. [SLIDE 14 — Lab and what's next] The lab has you build the signed inter-agent channel. Three pieces. First, a sign and verify message protocol with HMAC and durable keys — extending ZeroClaw's receipts with a persistent key store. Second, replay protection: nonces, a timestamp freshness window, and task binding. Third, an orchestrator-enforced compartment boundary, where a low-trust agent's request to a high-trust agent is mediated and authorized. The lab also includes a trust-escalation attack demo: a compromised low-trust agent forges an orchestrator message, and you watch the verification layer reject it. Next: B7, Sandboxes and Execution Controls. The code agent writes to staging — but what stops it escaping to the host? B7 builds the isolation primitive: containers, VMs, V8 isolates, syscall allowlists, resource limits. B6 authenticated the message. B7 contains the action. Let's build it.