Skip to content

Blast Radius

Forward graph walk from a single AWS resource, answering one question:

If this resource were compromised right now, what could an attacker reach?

This is the inverse of attack chain detection. Attack chains start from internet exposure and end at impact. Blast radius starts from a specific resource you care about (an EC2 instance, IAM role, Lambda, S3 bucket, secret) and walks outward through your saved scan to enumerate downstream identities, data, and final impact states.

Pair with the live visualizer

The JSON output (--format json) drops straight into the open visualizer at blast-audit.haitmg.pl — no install, no signup, no upload to a third-party cloud. Everything runs in your browser. The visualizer renders the same BlastRadiusGraph v1.0 schema with break-point highlighting, MITRE ATT&CK overlay, and an executive boardroom view for CFO/CISO briefings.

Workflow:

cloud-audit scan                                    # writes ~/.cloud-audit/last-scan.json
cloud-audit blast-radius --resource <ARN> \
                        --format json -o blast.json
# open https://blast-audit.haitmg.pl/demo/upload/
# drop blast.json into the upload area

Why a CLI tool?

Every existing AWS blast-radius capability we could verify in May 2026 is either paid SaaS, requires Neo4j + Cartography, or is unmaintained.

Tool Forward BFS from arbitrary AWS resource? Pure CLI? Last release
Wiz / Stream Security CloudTwin yes no (paid SaaS) active
Prowler App yes no (needs Neo4j) active
Prowler CLI no yes active
PMapper IAM-only, optimized for privesc-to-admin yes v1.1.5, Jan 2022
Cloudsplaining no (IAM policy analysis only) yes v0.8.2, Oct 2024
CloudFox no for AWS (lateral-movement GCP only) yes active
DetentionDodger IAM-only, only post-quarantine users yes v1.0, Oct 2024
awspx partial (graph + web UI) Docker v1.3.4, Aug 2021
ScoutSuite no yes v5.14.0, May 2024
Cartography no built-in - bring your own Cypher no (graph ingestor) active
BloodHound CE no for AWS (AD + Azure scope) no (web app) active
pathfinding.cloud no (it's a catalog) n/a n/a
Trivy no yes active

cloud-audit blast-radius aims to be a lightweight CLI-native alternative to the heavier setups: arbitrary AWS resource seeds (EC2, IAM, Lambda, S3, secret) and a documented JSON contract (BlastRadiusGraph v1.0) that other tools can consume, without standing up Neo4j or a SaaS backend.

Usage

# Use the last saved scan from ~/.cloud-audit/
cloud-audit blast-radius --resource i-0abc123def456

# Use a specific report file
cloud-audit blast-radius --resource arn:aws:iam::123456789012:role/deploy \
                        --report scan.json

# JSON output (BlastRadiusGraph v1.0 schema)
cloud-audit blast-radius --resource i-0abc123 \
                        --format json --output blast.json

# Mermaid diagram for docs / slides
cloud-audit blast-radius --resource i-0abc123 \
                        --format mermaid --output blast.mmd

# Markdown summary for PR comments
cloud-audit blast-radius --resource i-0abc123 \
                        --format markdown --output blast.md

# Bound the search
cloud-audit blast-radius --resource i-0abc123 --max-depth 3 --max-nodes 30

How it works

  1. Resource type detection - regex on the resource id / ARN. Supported: EC2 (i-XXX), IAM role (arn:aws:iam::*:role/*), IAM user, Lambda function ARN, S3 bucket ARN, Secrets Manager secret ARN.
  2. Seed node - the resource you specified, marked status=compromised.
  3. Compute -> identity link - for EC2 and Lambda seeds, find the attached / execution IAM role by inspecting attack-chain viz_steps from correlate.py (AC-01, AC-02, AC-05 etc.).
  4. Forward BFS from any IAM identity in the graph:
  5. Admin signal -> emit impact: Account Takeover node
  6. escalation_paths with method=AssumeRole:* -> emit lateral identity nodes
  7. For admin identities, scan findings for arn:aws:s3:::* and arn:aws:secretsmanager:* resources and emit them as storage nodes
  8. Stop conditions - max_depth (default 5) or max_nodes (default 50), whichever first.
  9. Narrative + fixes - group nodes by BFS step into a step-by-step storyline; pull remediation from any finding whose resource id appears in the graph.

Output: tree (default)

+------------------------------- Blast Radius --------------------------------+
| Compromise of i-0deadbeefcafebabe leads to Account Takeover via 2 hop(s).   |
| Resource: i-0deadbeefcafebabe                                               |
| Reachable: 3 | Paths to impact: 1 | Risk score: 52/100                      |
+-----------------------------------------------------------------------------+

i-0deadbeefcafebabe - EC2 instance (assumed compromised)
`-- prod-deploy-role - IAM Role attached to instance (via IMDS credentials, type=iam)
    `-- Account Takeover - Full AWS admin (via grants admin, type=exploit) <high-value>

Available fixes (from scan findings):
  - aws-ec2-004 IMDSv1 still callable (breaks chain, effort=LOW)
  - aws-iam-001 Role attached AdministratorAccess (breaks chain, effort=MEDIUM)

Output: JSON (BlastRadiusGraph v1.0)

The JSON format is the interop contract documented in cloud-audit-demo/src/types/blast-radius.ts. Field names are deliberately camelCase (highValue, bfsStep, actionTitle, actionDescription, codeExample, nodeIds) so the same payload feeds the demo's 3D visualization without any client-side normalisation.

Top-level shape:

{
  "schema_version": "1.0",
  "generated_at": "2026-05-15T08:30:00Z",
  "generator": {"name": "cloud-audit", "version": "2.3.0"},
  "source": {"type": "live-scan", "aws_account_id": "...", "region": "...", "resource_id": "..."},
  "summary": {"headline": "...", "risk_score": 52, "nodes_reachable": 3, "paths_found": 1, "stats": [...]},
  "graph": {"nodes": [...], "edges": [...]},
  "narrative": [{"step": 0, "title": "...", "description": "...", "nodeIds": [...]}],
  "fixes": [{"id": "...", "title": "...", "breaks_chain": true, "effort": "LOW", "cli_command": "...", "terraform": "...", "doc_url": "..."}],
  "cloud_audit_detects": [{"check_id": "...", "title": "...", "severity": "CRITICAL"}]
}

Node enum: internet | compute | identity | network | storage | finding | impact. Edge enum: network | iam | data | exploit. Status enum: external | safe | compromised | exploited | stolen | exfiltrated.

Output: Mermaid

graph TD
    seed_i_0deadbeefcafebabe["<b>i-0deadbeefcafebabe</b><br/>EC2 instance (assumed compromised)"]
    role_prod_deploy_role["<b>prod-deploy-role</b><br/>IAM Role attached to instance"]
    impact_account_takeover(("<b>Account Takeover</b><br/>Full AWS admin"))
    seed_i_0deadbeefcafebabe -- "IMDS credentials" --> role_prod_deploy_role
    role_prod_deploy_role -- "grants admin" --> impact_account_takeover

Compute nodes use cyan, identities pink, storage green, impact red. Pasteable into any Mermaid-aware renderer (GitHub, GitLab, Notion, Confluence, MkDocs).

Limits in v2.3.0 (MVP)

This release is the MVP that ships ahead of the full v3.0.0 Security Graph release. The following are intentionally out of scope and will land with v3.0.0:

  • Network reachability (VPC peering, TGW, on-prem CIDR overlap)
  • Cross-account propagation through trust policies
  • Permission boundary / SCP semantic evaluation
  • Data classification (PII / PCI / PHI tagging on buckets / secrets)
  • Custom storytelling templates beyond the static initial set
  • HTML report integration
  • MCP server tool wrapping (compute_blast_radius)
  • S3 / secret seed backward expansion to "who has access?" view

If you need any of these for an engagement before v3.0.0, run the seed-side analysis manually using cloud-audit scan --format json -o scan.json followed by cloud-audit blast-radius --resource <id> --report scan.json on each resource of interest.

Risk score

A simple, documented heuristic:

Contribution Score
Any impact node reachable +50
Lateral identity reachable +20
High-value storage reachable +20
Each reachable node up to 10 +1

Capped at 100. This is not a calibrated metric - treat it as a "needle moves in the right direction" indicator, not a CVSS replacement.

Pre-loaded historical scenarios in the visualizer

blast-audit.haitmg.pl ships with seven high-profile breach scenarios pre-built from primary-source disclosures. Each one carries verified facts, primary citations, and an executive boardroom view (?board=1) suitable for CISO/CFO briefings.

Scenario Year Pattern URL
Capital One 2019 SSRF + IMDSv1 + over-permissive WAF role /demo/capital-one-2019/
Cryptomining 2025 Leaked AKID + 14 ASGs spinning /demo/cryptomining-2025/
Bedrock AgentCore 2026 Sandbox bypass via DNS resolver /demo/agentcore-2026/
Snowflake / UNC5537 2024 Infostealer creds replayed against no-MFA tenants /demo/snowflake-unc5537-2024/
nx Supply Chain / UNC6426 2026 Trojanised npm + LLM stealer + GitHub OIDC /demo/unc6426-nx-2026/
Codefinger 2025 AWS-native SSE-C ransomware (no key recovery) /demo/codefinger-ssec-2025/
Trivy / TeamPCP 2026 GitHub Action tag force-push → credential stealer /demo/trivy-teampcp-2026/

The visualizer's boardroom mode includes a one-click counterfactual ("What stops this attack?") that animates the exposure tile to $0 when you preview the recommended IAM remediation — useful for "here's why this matters" framing in executive review meetings.

Boardroom briefing PDF

In boardroom mode, the Download briefing button calls window.print() against a dedicated .print-briefing block in the visualizer's DOM. The result is a single-page A4 PDF with the executive narrative, three big tiles (exposure / time-to-detect / fix complexity), and the Friday-ask prompt — ready to forward to a CEO before a board review without any cyberpunk chrome.