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:
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
- 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. - Seed node - the resource you specified, marked
status=compromised. - Compute -> identity link - for EC2 and Lambda seeds, find the
attached / execution IAM role by inspecting attack-chain
viz_stepsfromcorrelate.py(AC-01, AC-02, AC-05 etc.). - Forward BFS from any IAM identity in the graph:
- Admin signal -> emit
impact: Account Takeovernode escalation_pathswithmethod=AssumeRole:*-> emit lateral identity nodes- For admin identities, scan findings for
arn:aws:s3:::*andarn:aws:secretsmanager:*resources and emit them as storage nodes - Stop conditions -
max_depth(default 5) ormax_nodes(default 50), whichever first. - Narrative + fixes - group nodes by BFS step into a step-by-step
storyline; pull
remediationfrom 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.