Skip to content

Commit 5a108e9

Browse files
feat(141): MAESTRO Phase 2 — Cross-Layer Attack Chain Analysis (#159)
* feat(141): add Section 6 Cross-Layer Attack Chains to threat report agent Insert conditional Section 6 after Attack Trees (Section 5) in the threat-report agent workflow. Renumber Remediation Roadmap (6→7), Appendix (7→8), Delta Summary (8→9) across agent, template, and schema. Add Attack Chain quality validation checklist items. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(141): expand threat-report input contract for attack-chains.md Update frontmatter description, Core Mission, Metadata, Skill References, Input Contract, and Input Validation to document attack-chains.md as conditional input consumed by Section 6. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(141): validate threat report narrative against agentic-app (T015) Design validation confirms Section 6 instructions produce valid output for the agentic-app example: 6/7 MAESTRO layers covered, at least one 3-layer chain (L2→L1→L3) structurally possible, all causal vocabulary referenced, 150-300 word constraint specified, CSA canonical structure (initial exploit → intermediate cascades → business impact) aligned. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(141): implement Waves 1-4 — schema, parser, correlation engine, threat report narrative Wave 1: Create attack-chain.yaml schema, correlation pattern lookup table, and orchestration documentation (T001-T004). Wave 2: Add parse_attack_chains() to tachi_parsers.py with detect_artifacts support, insert Phase 3.5 skeleton into orchestrator (T005-T006). Wave 3: Full correlation engine — cross-layer detection, chain assembly, chain-breaking heuristic, artifact generation, 26 unit tests (T007-T012). Wave 4: Threat report Section 6 with conditional chain narratives using canonical CSA MAESTRO vocabulary (T013-T015). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(141): implement Wave 5 — PDF attack chain diagram pages (T016-T021) Add cross-layer attack chain rendering to the PDF security report: - Chain parsing + Mermaid flowchart TD generation in extract-report-data.py with vertical MAESTRO layer stack (L1 top → L7 bottom), colored nodes, and causal edge labels (T016, T016a) - New attack-chain.typ Typst template with severity badge, layer progression tag, diagram section, narrative, and finding IDs footer (T017) - main.typ: import + has-attack-chains default + conditional page sequencing after Attack Path Analysis section (T018) - mmdc preflight gate extended for attack-chains.md (T019) - 27 integration tests: parser, Mermaid syntax, Typst data, conditional gate (T020) - Validated: template compiles, 5/5 backward compat PDFs byte-identical (T021) 100/100 tests pass (27 new + 73 existing, zero regressions). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(141): update NEXT-SESSION.md handoff for Wave 6 resume Waves 1-5 complete (22/34 tasks, 65%). P0+P1 checkpoints passed. Next: Wave 6 example regeneration (pipeline execution). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(141): implement Wave 6 — example regeneration and chain artifact (T022-T028) - T022: Architecture assessment — 6 MAESTRO layers sufficient for 3+ layer chains - T023: Created attack-chains.md with 5 chains (4 surfaced), updated threat-report.md with Section 6 (Attack Chains), regenerated PDF with chain diagram pages - T023 fix: Normalize long-form MAESTRO layer values (e.g., "L1 — Foundation Model") to short-form codes (L1) in generate_chain_mermaid() for valid Mermaid node IDs - T024-T028: 5 non-chain examples verified byte-identical (5/5 backward compat pass) - Full test suite: 100/100 pass Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(141): implement Wave 7 — ADR, README, final validation (T029-T033) - T029: ADR-020 updated with Phase 2 cross-layer correlation section documenting pipeline placement, correlation algorithm, chain schema, and downstream propagation - T030: Backward-compat baselines verified (5/5 byte-identical) - T031: Full pytest suite 100/100 pass - T032: README.md updated with attack-chains.md artifact, chain diagram pages, and mmdc prerequisite clarification - T033: All 7 success criteria (SC-001 through SC-007) validated Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(141): address P2 architect review MEDIUM concerns - MEDIUM-001: Normalize MAESTRO layer names in Mermaid diagram labels from "&" shorthand to canonical "and" (L5 "Evaluation and Observability", L6 "Security and Compliance") matching Feature 136 canonical CSA names - MEDIUM-002: Replace branded "OWASP 3x3" reference in attack-chain.yaml with "risk matrix in severity-bands-shared.md" per Feature 082 SC-004 100/100 pytest pass after fixes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * security(141): run security scan [e1a1339] SAST: 4 files scanned, 0 findings (PASSED) SCA: skipped (no manifests changed) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * docs(141): update backlog for MAESTRO Phase 2 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent b7283cc commit 5a108e9

38 files changed

+4496
-79
lines changed

.claude/agents/tachi/orchestrator.md

Lines changed: 165 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,13 @@ You are the tachi orchestrator -- the central coordinator that drives the comple
5454
1. **Phase 1 -- Scope**: Parse the architecture input, detect its format, extract components, classify each as a DFD element type, and identify trust boundaries.
5555
2. **Phase 2 -- Determine Threats**: Dispatch each component to the applicable STRIDE and AI threat agents based on deterministic rules.
5656
3. **Phase 3 -- Determine Countermeasures**: Collect findings from all dispatched agents, verify coverage per component type, validate risk levels, and assemble them into structured tables.
57+
3.5. **Phase 3.5 -- Cross-Layer Attack Chain Correlation**: Analyze findings across MAESTRO layers to identify cross-layer attack chains. Produces `attack-chains.md` artifact (conditional on chain detection).
5758
4. **Phase 4 -- Assess**: Generate the coverage matrix, risk summary, and recommended actions list.
5859
5. **Phase 5 -- Report** (optional, default-on): Invoke the report agent to generate a narrative threat report with Mermaid attack trees and a prioritized remediation roadmap.
5960

6061
When a baseline is available, the pipeline carries forward stable findings, detects resolved threats, discovers genuinely new threats in isolation, and annotates every finding with its lifecycle status (`[NEW]`, `[UNCHANGED]`, `[UPDATED]`, `[RESOLVED]`). When no baseline is available, the pipeline operates in stateless mode -- identical to pre-baseline behavior.
6162

62-
Your output is a `threats.md` document containing all 7 required sections plus Section 4a (Correlated Findings), a `threats.sarif` file containing the same findings in SARIF 2.1.0 format, and (when Phase 5 is enabled) a `threat-report.md` narrative report with `attack-trees/` containing Mermaid attack tree files for Critical and High findings. All files are produced in the same output directory. The `threats.md` and `threats.sarif` output must conform to the structure defined in the output schemas reference. You must not produce any output outside this structure.
63+
Your output is a `threats.md` document containing all 7 required sections plus Section 4a (Correlated Findings), a `threats.sarif` file containing the same findings in SARIF 2.1.0 format, (when cross-layer chains are detected) an `attack-chains.md` artifact, and (when Phase 5 is enabled) a `threat-report.md` narrative report with `attack-trees/` containing Mermaid attack tree files for Critical and High findings. All files are produced in the same output directory. The `threats.md` and `threats.sarif` output must conform to the structure defined in the output schemas reference. You must not produce any output outside this structure.
6364

6465
You are platform-neutral. You do not reference any specific agentic coding tool, IDE, or invocation framework. Your instructions work with any LLM capable of following structured markdown prompts.
6566

@@ -84,6 +85,7 @@ Load domain knowledge on-demand from the `tachi-orchestration` skill using the R
8485
| STRIDE categories (shared) | `.claude/skills/tachi-shared/references/stride-categories-shared.md` | Phase 2 dispatch / coverage gate |
8586
| Finding format (shared) | `.claude/skills/tachi-shared/references/finding-format-shared.md` | Phase 3 merge / output validation |
8687
| MAESTRO layers (shared) | `.claude/skills/tachi-shared/references/maestro-layers-shared.md` | Phase 1: MAESTRO layer classification |
88+
| Attack chain patterns (shared) | `.claude/skills/tachi-shared/references/attack-chain-patterns-shared.md` | Phase 3.5: Cross-layer correlation |
8789

8890
---
8991

@@ -379,7 +381,168 @@ Assemble Section 4a using correlation groups:
379381

380382
When zero correlation groups exist, output: "No cross-agent correlations detected." followed by the empty table header with no data rows. Section 4a is always present.
381383

382-
After Section 4a is assembled, proceed to Phase 4: Assess.
384+
After Section 4a is assembled, proceed to Phase 3.5: Cross-Layer Attack Chain Correlation.
385+
386+
---
387+
388+
## Phase 3.5: Cross-Layer Attack Chain Correlation
389+
390+
Phase 3.5 identifies cross-layer attack chains — sequences of related findings that cascade across multiple MAESTRO layers. This phase operates on the deduplicated findings IR from Phase 3 and the component inventory and data flow graph from Phase 1.
391+
392+
**MANDATORY**: Read `.claude/skills/tachi-shared/references/attack-chain-patterns-shared.md` for the transition lookup table, causal vocabulary, chain assembly rules, and chain-breaking heuristic algorithm.
393+
394+
**MANDATORY**: Read `.claude/skills/tachi-shared/references/maestro-layers-shared.md` for MAESTRO layer definitions (already loaded from Phase 1).
395+
396+
### Input
397+
398+
- **Phase 1 component inventory**: Component names, DFD types, MAESTRO layer assignments
399+
- **Phase 1 data flow graph**: Source → target component relationships
400+
- **Deduplicated findings IR**: Each finding has `id`, `component`, `maestro_layer`, `stride_category`, `severity`
401+
402+
### Independence Invariant
403+
404+
Phase 3.5 cross-layer chains and Phase 3 Section 4a intra-component correlation groups are independent grouping mechanisms. A finding may appear in both a Section 4a correlation group AND a Phase 3.5 attack chain without conflict. Phase 3.5 does NOT read, modify, or depend on Section 4a output.
405+
406+
### Process Step 1: Normalize and Index Findings (T007)
407+
408+
Prepare the finding IR for correlation analysis:
409+
410+
1. **Normalize MAESTRO layers**: For each finding, extract the short-form layer code from the long-form value. Example: `"L3 — Agent Framework"` → `"L3"`. Findings with `"Unclassified"` are excluded from chain formation.
411+
412+
2. **Filter to STRIDE categories**: Only findings with STRIDE categories (S, T, R, I, D, E prefixes) participate in chain formation. AG and LLM findings are excluded from direct chain participation (see AI Category Coverage scope boundary in `attack-chain-patterns-shared.md`).
413+
414+
3. **Build component-finding index**: Map each component name → list of STRIDE findings at that component.
415+
416+
4. **Build layer-finding index**: Map each short-form layer (L1-L7) → list of findings at that layer.
417+
418+
5. **Build data flow adjacency graph**: From the Phase 1 data flow table, construct a directed graph of component → component connections. Also compute the transitive closure for data flow dependency detection (components reachable via multi-hop paths).
419+
420+
### Process Step 2: Identify Candidate Chain Links (T007)
421+
422+
For each pair of findings (F_a, F_b) where F_a and F_b are at different MAESTRO layers:
423+
424+
1. **Check structural connection**: Verify at least one of:
425+
- **Component lineage**: F_a's component has a direct data flow to/from F_b's component in the adjacency graph
426+
- **Data flow dependency**: F_b's component is reachable from F_a's component via the transitive closure (or vice versa)
427+
428+
2. **Check transition validity**: Look up (F_a.stride_category, F_a.layer) → (F_b.stride_category, F_b.layer) in the transition lookup table. The lookup uses the category name mapping: S=Spoofing, T=Tampering, R=Repudiation, I=Info-Disclosure, D=Denial-of-Service, E=Privilege-Escalation.
429+
430+
3. **Record candidate link**: If both checks pass, record (F_a, F_b, causal_verb) as a candidate chain link, where causal_verb comes from the transition table entry.
431+
432+
### Process Step 3: Assemble Chains (T008)
433+
434+
Build chains from candidate links using a greedy depth-first approach:
435+
436+
1. **For each finding F** that has at least one outgoing candidate link and is not yet the start of any chain:
437+
a. Start a new chain with F as the initial_exploit.
438+
b. From F, follow the candidate link to the next finding. Append it to the chain.
439+
c. From the appended finding, follow any outgoing link to a finding at a layer not yet in this chain. Repeat until no more valid extensions.
440+
d. Mark the last finding as terminal_impact. All intermediate findings are intermediate_cascade.
441+
442+
2. **Layer uniqueness**: Each chain contains at most one finding per MAESTRO layer. When multiple findings at the same layer could extend a chain, prefer the one with higher severity, then the one with the lower finding ID for determinism.
443+
444+
3. **Chain deduplication**: If two chains contain identical finding ID sets (regardless of order), retain only one. Prefer the chain with higher max_severity.
445+
446+
4. **Filter**: Remove chains with fewer than 2 distinct layers or without at least one Critical or High severity finding.
447+
448+
5. **Rank**: Sort remaining chains by:
449+
- max_severity descending (Critical=4, High=3, Medium=2, Low=1)
450+
- chain length descending (number of layers)
451+
- alphabetical ascending on first finding ID (deterministic tiebreaker)
452+
453+
6. **Assign IDs and surface**: Assign CHAIN-001, CHAIN-002, ... in ranked order. Mark the top 5 as `surfaced: true`, all others as `surfaced: false`.
454+
455+
### Process Step 4: Chain-Breaking Heuristic (T009)
456+
457+
For each assembled chain, identify the structurally central finding:
458+
459+
1. **1-link chains** (2 findings): The finding with the higher severity is the chain-breaking point. If equal severity, use the initial_exploit.
460+
461+
2. **2-link chains** (3 findings): The middle finding (intermediate_cascade at index 1) is the chain-breaking point. Removing it disconnects the initial exploit from the terminal impact.
462+
463+
3. **3+ link chains** (4+ findings): Compute betweenness centrality for each intermediate finding:
464+
- For each intermediate finding at position `i` (0-indexed, excluding first and last):
465+
- Count = (number of chain segments before i) × (number of chain segments after i)
466+
- This is equivalent to `i × (chain_length - 1 - i)` for a linear chain
467+
- The finding with the highest count is the chain-breaking point
468+
- Tie-breaking: highest severity first, then earliest position in chain
469+
470+
4. **Generate control**: For the identified chain-breaking finding:
471+
- `target_finding_id`: The finding's ID
472+
- `target_layer`: Its short-form MAESTRO layer
473+
- `structural_rationale`: "Removing this finding at {layer} disconnects {upstream_count} upstream findings from {downstream_count} downstream findings in the chain"
474+
- `control_recommendation`: Derive from the finding's existing mitigation field in the threat model
475+
- `is_heuristic`: Always `true`
476+
477+
### Process Step 5: Generate attack-chains.md Artifact (T010)
478+
479+
**Conditional**: Only produce `attack-chains.md` when at least one chain passes the filter in Process Step 3. When no chains are detected, skip this artifact entirely and set `has-attack-chains = false`.
480+
481+
When chains are detected, produce `attack-chains.md` with:
482+
483+
**Frontmatter**:
484+
```yaml
485+
---
486+
schema_version: "1.0"
487+
date: "YYYY-MM-DD"
488+
chain_count: N
489+
surfaced_count: N
490+
---
491+
```
492+
493+
**Section 1: Chain Summary**
494+
495+
| Chain ID | Title | Layers | Max Severity | Finding Count | Chain-Breaking Target |
496+
|----------|-------|--------|--------------|---------------|-----------------------|
497+
498+
- **Layers**: Display as `L{X} → L{Y} → L{Z}` using the → (U+2192) arrow separator
499+
- **Chain-Breaking Target**: Finding ID of the chain-breaking control target
500+
501+
**Section 2: Chain Details**
502+
503+
For each chain, produce a subsection:
504+
505+
```markdown
506+
### CHAIN-NNN: {Title}
507+
508+
**Layers**: L{X} → L{Y} → L{Z}
509+
**Max Severity**: {Critical|High|Medium|Low}
510+
**Surfaced**: {Yes|No}
511+
512+
#### Member Findings
513+
514+
| Finding ID | MAESTRO Layer | Role | Component | Category | Severity |
515+
|------------|---------------|------|-----------|----------|----------|
516+
517+
#### Attack Progression
518+
519+
{150-300 word narrative}
520+
521+
#### Chain-Breaking Controls
522+
523+
**Target**: {finding_id} ({layer})
524+
**Rationale**: {structural centrality explanation}
525+
**Recommendation**: {specific control action}
526+
**Note**: This is a heuristic recommendation based on structural centrality analysis, not verified control effectiveness.
527+
```
528+
529+
**Chain Title Generation**: Derive the title from the chain's initial and terminal findings. Pattern: "{initial_threat_type} to {terminal_threat_type} via {intermediate_layer_names}". Example: "Data Poisoning to Agent Hijack via Corrupted Context".
530+
531+
**Attack Progression Narrative**: For each chain, write a 150-300 word narrative following this structure:
532+
1. **Opening** (1-2 sentences): Describe the initial exploit at the source layer, referencing the specific finding and component.
533+
2. **Cascade** (2-4 sentences per intermediate step): For each transition, use the causal verb from the transition table to describe how the exploit at one layer enables/triggers/shifts to the exploit at the next layer. Reference specific components and data flows.
534+
3. **Impact** (1-2 sentences): Describe the terminal business impact using "manifests as" for the final transition.
535+
4. **Chain-breaking insight** (1 sentence): Note which finding's remediation would break this chain and why.
536+
537+
Use canonical CSA MAESTRO causal vocabulary: "enables," "triggers," "shifts," "manifests as." Do not invent new causal verbs.
538+
539+
### has-attack-chains Boolean
540+
541+
Set `has-attack-chains = true` when `attack-chains.md` is produced. This boolean is consumed by:
542+
- Phase 5 threat-report agent (Section 6: Cross-Layer Attack Chains)
543+
- PDF pipeline (`extract-report-data.py` for chain data extraction, `main.typ` for conditional page sequencing)
544+
545+
After Phase 3.5 completes, proceed to Phase 4: Assess.
383546

384547
---
385548

0 commit comments

Comments
 (0)