IAM Blast Radius UI: blast map graph, per-principal scores, 17 findings and 14 verified fixes for the acme-prod sample
The acme-prod sample report (top section shown; the full page continues with all 17 findings and 14 verified fixes): critical posture, a blast map of who can become whom, and blast radius per principal.

A list of IAM bindings does not tell you how bad a compromise would be, because roles chain. A service account that can create keys for another service account, which holds Owner, is Owner. gcp-iam-blast-radius answers one question about a project: if this identity is compromised, what can it become? It reads project IAM read-only, follows service-account impersonation chains, scores every principal's blast radius from 0 to 100, flags privilege-escalation paths and proposes least-privilege fixes. Every fix is re-simulated against the policy before it is shown, so a suggestion that would widen access or lock you out of IAM is rejected automatically.

How it computes "can become"

The engine derives direct capabilities per principal, then adds "can become" edges between service accounts: token creator, key creation, actAs combined with code execution, and IAM admin. A principal's effective score is what it can reach through those hops. Ten deterministic rules own severity and the overall posture. In the acme-prod sample, user:bob has a direct score of 20 but an effective score of 100, through bob to the compute service account (Editor) to the terraform service account (Owner).

The trust split

Code decides severity, posture and which fixes are valid. Models only explain and propose, and both are validated. An explanation must mention only identities and roles that exist in the snapshot and contain no links. A proposed patch must reference a real binding, must not add capabilities, and must lower total blast radius when simulated. The cross-provider eval (18 runs) saw 0 invariant violations: posture and findings were identical to rules-only, and every fix was re-verified. Models did propose bad patches: gemini-2.5-flash and gpt-5-nano each had 12 accepted and 4 rejected by the simulator, the mock 14 and 2.

Reading the sample report

The acme-prod sample is critical: 13 principals, 17 findings, 14 verified fixes. The blast map shows critical identities as large red nodes with arrows for "can become" edges. Findings include a group that can escalate from score 86 to 100 by creating a key for a service account, a CI deployer that can mint tokens for the compute service account, roles/storage.objectViewer granted to allUsers, primitive Editor and Owner roles on service accounts and a user, a user-managed key 210 days old, an external gmail identity holding storage.admin, and a disabled service account that still holds roles. Further down, each fix shows its accepted effect on the total, for example "remove serviceAccountUser from bob: total blast radius 803 to 718", with the exact gcloud projects remove-iam-policy-binding command. Where a narrower role is needed it is added before the old one is removed.

Model-proposed fixes appear in the same list with their label, such as replacing roles/editor on a service account with roles/compute.instanceAdmin.v1, accepted because simulation shows the total drops from 803 to 708. The orchestration timeline at the bottom shows the engine in 1 ms, four analyst and four planner model calls in parallel, then the verifier and judge.

A real project

IAM Blast Radius analysing a live project with 39 principals
A live read-only analysis of a real project on Cloud Run: 39 principals, 2 findings, 2 verified fixes.

The second screenshot is a live analysis of one of my own projects on Cloud Run: 39 principals, 2 findings, 2 verified fixes, for $0.001. Live mode only analyses projects on an allow-list (IAMBLAST_LIVE_PROJECTS), the service account holds iam.securityReviewer, and results live in memory only.

CheckResult
Offline tests58 pass: engine hops, cycles, disabled SAs, every rule, patch verification, hostile-model cases
DeployedUnauthenticated, openai provider and non-allow-listed project all 403

Limits

The role catalog is a curated 75-role approximation, not IAM's permission lists. Unlisted roles are reported as IAM009 and not scored, so radii can be understated; confirm important fixes with Policy Analyzer. Scope is project and service-account IAM; resource-level policies, folder and org inheritance, deny policies, conditions and group membership are not expanded. Fixes are verified against a model of access, not actual usage, so a "safe" removal can break a workload: check audit logs first. It was verified on three synthetic snapshots and one small real project, and large estates are untested.

Try it yourself

git clone https://github.com/soodrajesh/gcp-iam-blast-radius
cd gcp-iam-blast-radius
.venv/bin/iamblast analyze iamblast/samples/acme_prod.json --llm none # exit 2 = critical
.venv/bin/iamblast collect my-project --internal-domain example.com > snapshot.json

📢 Have questions or feedback? Drop a comment below or connect with me on Twitter/X@spysood!