Attack chains are defined as YAML files. QAI includes reference templates for common AI system architectures. Use templates as starting points for custom chains.
Chain YAML Structure
A chain definition consists of metadata and an ordered list of steps:
id: my-chain-id
name: My Attack Chain
category: agent_delegation
description: >
A description of what this chain demonstrates and what
vulnerabilities it exploits across the target architecture.
steps:
- id: step-1
name: First step description
module: inject
technique: output_injection
trust_boundary: tool-to-agent
on_success: step-2
on_failure: abort
terminal: false
- id: step-2
name: Second step description
module: audit
technique: injection
trust_boundary: agent-to-agent
on_success: step-3
on_failure: abort
terminal: false
- id: step-3
name: Final step
module: inject
technique: description_poisoning
trust_boundary: agent-to-tool
terminal: true
Top-Level Fields
| Field | Type | Required | Description |
|---|
id | string | Yes | Unique identifier (kebab-case recommended) |
name | string | Yes | Human-readable chain name |
category | string | Yes | Architecture category: rag_pipeline, agent_delegation, mcp_ecosystem, or hybrid |
description | string | Yes | Detailed description of what the chain demonstrates |
steps | array | Yes | List of attack steps in execution order |
entry_cves | array | No | Optional CVE IDs used as entry points |
Step Fields
| Field | Type | Required | Description |
|---|
id | string | Yes | Unique step identifier within the chain |
name | string | Yes | Human-readable step description |
module | string | Yes | Which qai module provides this step: audit, inject, ipi, cxp, or rxp |
technique | string | Yes | Specific technique within the module |
depends_on | array | No | List of step IDs that must succeed before this step |
trust_boundary | string | No | System boundary crossed by this step |
on_success | string | No | Step ID to execute on success, or abort to end chain |
on_failure | string | No | Step ID to execute on failure (default: abort) |
terminal | boolean | No | Whether this is the final step (default: false) |
inputs | object | No | Input parameters for live execution (ignored in dry-run). Set manual_gate: true for IPI/CXP steps that require human action before continuing |
relevant_categories | array | No | Audit finding categories this step is relevant to (e.g., tool_poisoning, command_injection). Used for coverage tracking and entry point matching |
Trust Boundaries
Trust boundaries identify system crossings during an attack:
| Boundary | Meaning |
|---|
client-to-server | External input entering the system |
tool-to-agent | Tool output influencing agent reasoning |
agent-to-tool | Agent invoking a tool |
agent-to-agent | One agent influencing another |
llm-to-agent | LLM output shaping agent behavior |
user-to-system | User input entering application logic |
agent-to-data | Agent accessing data stores or retrieval layers |
attacker-to-document | Attacker-crafted content entering document ingestion |
attacker-to-context | Poisoned context files entering IDE/assistant |
corpus-to-retriever | Document corpus influencing retrieval ranking |
retriever-to-agent | Retrieved content shaping agent behavior |
agent-to-server | Agent-generated code deployed as server |
Built-in Templates
delegation-hijack
Category: agent_delegation
Exploit weak tool trust boundaries to hijack agent delegation. Inject instructions via tool output, escalate through cross-tool trust, then manipulate downstream agent behavior.
id: delegation-hijack
name: Agent Delegation Hijack
category: agent_delegation
description: >
Exploit weak tool trust boundaries to hijack agent delegation.
Inject via output channel, escalate through cross-tool trust,
then manipulate downstream agent behavior via description poisoning.
steps:
- id: inject-output
name: Inject instructions via tool output
module: inject
technique: output_injection
trust_boundary: tool-to-agent
on_success: cross-tool-pivot
on_failure: abort
- id: cross-tool-pivot
name: Pivot through cross-tool delegation
module: inject
technique: cross_tool_escalation
trust_boundary: agent-to-agent
on_success: poison-downstream
on_failure: abort
- id: poison-downstream
name: Poison downstream agent tool descriptions
module: inject
technique: description_poisoning
trust_boundary: agent-to-tool
terminal: true
mcp-server-compromise
Category: mcp_ecosystem
Discover command injection vulnerability via audit scan, exploit via tool poisoning to manipulate agent behavior, then escalate across tools to reach sensitive data.
id: mcp-server-compromise
name: MCP Server Compromise
category: mcp_ecosystem
description: >
Discover command injection via audit scan, exploit via
tool poisoning to manipulate agent behavior, then
escalate across tools to reach sensitive data.
steps:
- id: scan-injection
name: Identify command injection vulnerability
module: audit
technique: injection
trust_boundary: client-to-server
on_success: poison-tool
on_failure: abort
- id: poison-tool
name: Poison vulnerable tool description
module: inject
technique: description_poisoning
trust_boundary: agent-to-tool
on_success: cross-tool-exfil
on_failure: abort
- id: cross-tool-exfil
name: Exfiltrate via cross-tool escalation
module: inject
technique: cross_tool_escalation
trust_boundary: agent-to-agent
terminal: true
rag-trust-escalation
Category: rag_pipeline
Poison a tool description to inject malicious instructions, escalate through cross-tool agent delegation, then exfiltrate data via output injection. Demonstrates three trust boundary crossings in a single attack path.
id: rag-trust-escalation
name: RAG Trust Escalation
category: rag_pipeline
description: >
Poison a tool description to inject malicious instructions,
escalate through cross-tool agent delegation, then exfiltrate
data via output injection. Demonstrates three trust boundary
crossings in a single attack path.
steps:
- id: poison-tool
name: Inject payload via poisoned tool description
module: inject
technique: description_poisoning
trust_boundary: agent-to-tool
on_success: escalate-cross-tool
on_failure: abort
- id: escalate-cross-tool
name: Escalate through cross-tool delegation
module: inject
technique: cross_tool_escalation
trust_boundary: agent-to-agent
on_success: exfil-output
on_failure: abort
- id: exfil-output
name: Exfiltrate data via output injection
module: inject
technique: output_injection
trust_boundary: agent-to-data
terminal: true
document-poisoning
Category: hybrid
Generate IPI payloads, pause for human deployment into a target agent’s ingestion pipeline, then audit scan the target to check for exploitation evidence.
id: document-poisoning
name: Document Poisoning Chain
category: hybrid
description: >
Generate IPI payloads (poisoned documents), pause for human deployment
into a target agent's ingestion pipeline, then audit scan the target
MCP server to check if the agent called vulnerable tools after
ingesting the poisoned document. Demonstrates IPI -> audit cross-cluster path.
steps:
- id: generate-payloads
name: Generate IPI document payloads
module: ipi
technique: pdf
trust_boundary: attacker-to-document
on_success: scan-target
on_failure: abort
inputs:
manual_gate: true
relevant_categories:
- indirect_prompt_injection
- id: scan-target
name: Audit scan target server for exploitation evidence
module: audit
technique: injection
trust_boundary: agent-to-tool
terminal: true
relevant_categories:
- command_injection
- tool_poisoning
context-poisoning
Category: hybrid
Build a poisoned context file repo, pause for human to test in a coding assistant, then audit scan the generated server for vulnerabilities.
id: context-poisoning
name: Context Poisoning Chain
category: hybrid
description: >
Build a poisoned context file repo (CXP), pause for human to open
in a coding assistant and run the trigger prompt, then audit scan
the generated server to check if it contains vulnerabilities.
Demonstrates CXP -> audit cross-cluster path.
steps:
- id: build-repo
name: Build poisoned context file repository
module: cxp
technique: cursorrules
trust_boundary: attacker-to-context
on_success: scan-generated
on_failure: abort
inputs:
manual_gate: true
relevant_categories:
- context_file_poisoning
- id: scan-generated
name: Audit scan generated server for vulnerabilities
module: audit
technique: injection
trust_boundary: agent-to-server
terminal: true
relevant_categories:
- command_injection
- permissions
rag-validation
Category: rag_pipeline
Validate that poison documents achieve high retrieval rank, then generate IPI payloads targeting the retrieval path.
id: rag-validation
name: RAG Validation Chain
category: rag_pipeline
description: >
Validate that poison documents are retrieved by the RAG pipeline
(RXP), then generate IPI payloads targeting the retrieval path,
pause for human deployment. Demonstrates RXP -> IPI pipeline as a chain.
steps:
- id: validate-retrieval
name: Validate poison document retrieval
module: rxp
technique: minilm-l6
trust_boundary: corpus-to-retriever
on_success: generate-ipi
on_failure: abort
relevant_categories:
- rag_poisoning
- id: generate-ipi
name: Generate IPI payloads for retrieval path
module: ipi
technique: pdf
trust_boundary: retriever-to-agent
terminal: true
inputs:
manual_gate: true
relevant_categories:
- indirect_prompt_injection
Writing Custom Chains
-
Define the attack hypothesis — What architecture are you targeting? What vulnerabilities will you exploit?
-
Identify steps — Break down the attack into sequential techniques:
steps:
- id: reconnaissance
name: Identify target tools
module: audit
technique: injection
on_success: exploitation
- id: exploitation
name: Exploit vulnerability
module: inject
technique: output_injection
on_success: escalation
- id: escalation
name: Escalate privileges
module: inject
technique: cross_tool_escalation
terminal: true
- Map trust boundaries — Document which system boundaries each step crosses:
- id: exploit
trust_boundary: tool-to-agent
on_success: escalate
- Validate the chain structure:
qai chain validate --chain-file my_chain.yaml
- Dry-run to trace the path:
qai chain run --chain-file my_chain.yaml --dry-run
- Execute against real targets (if applicable):
qai chain run --chain-file my_chain.yaml \
--targets ~/.qai/chain-targets.yaml \
--no-dry-run
Module & Technique Reference
Chain steps reference two modules. The validator checks that each step’s module and technique are valid.
audit module
Any of the 10 audit scanner names can be used as a technique. These are the same names used with --checks on qai audit scan:
injection, auth, token_exposure, permissions, tool_poisoning, prompt_injection, audit_telemetry, supply_chain, shadow_servers, context_sharing
inject module
Three injection technique categories:
description_poisoning — Embed instructions in MCP tool descriptions
output_injection — Inject instructions into tool response content
cross_tool_escalation — Chain trust across multiple tools to escalate
ipi module
IPI steps generate poisoned documents. The technique field is the document format:
pdf, md, html, docx, ics, eml, image
IPI steps typically use manual_gate: true in their inputs, since the researcher must deploy the generated documents to the target system before the chain continues.
cxp module
CXP steps build poisoned context file repositories. The technique field is the format ID:
cursorrules, claude-md, copilot-instructions, windsurf, cline, aider, codex, devin
CXP steps typically use manual_gate: true, since the researcher must open the repo in a coding assistant and run the trigger prompt.
rxp module
RXP steps validate retrieval poisoning. The technique field is the embedding model ID:
minilm-l6, minilm-l12, bge-small, or any HuggingFace sentence-transformers model name.
RXP requires the optional [rxp] dependencies.
Five modules are valid chain steps: audit, inject, ipi, cxp, and rxp. The proxy module is not a chain step — it operates as background traffic capture correlated to chain execution via chain_run_id and chain_step_id fields on proxy sessions.
Best Practices
Sequencing
- List steps in logical execution order
- Use
on_success and on_failure for control flow
- Mark the final step with
terminal: true
Naming
- Use descriptive step names (kebab-case for IDs)
- Include the technique name for clarity
- Document the trust boundary impact
Dependencies
- Keep dependencies explicit with
on_success transitions
- Avoid cycles (chains must be DAGs)
- Make failure handling clear with
on_failure
Documentation
- Write detailed descriptions explaining the attack
- Include the architecture being targeted
- Document entry points if applicable
Start from a built-in template and customize it for your specific architecture. Templates are reference implementations validated against real systems.