Agent Blast-Radius

shieldly agent-scan answers one question: what could this AI agent's AWS credentials destroy, exfiltrate, or escalate to? Included in every Shieldly plan, same price — no new SKU.

Quickstart

npm install -g @shieldly/cli

Run it with no arguments in a project that has an agent config (.mcp.json, Claude Code settings, Claude Desktop, Cursor, Windsurf, VS Code) — it auto-discovers the config and any AWS profile or role it references:

shieldly agent-scan

Or point it at an input explicitly:

shieldly agent-scan --policy-file agent-policy.json
shieldly agent-scan --role-arn arn:aws:iam::123456789012:role/my-agent
shieldly agent-scan --cfn-file cdk.out/MyStack.template.json
shieldly agent-scan --sarif > results.sarif

Inputs

FlagWhat it analyzes
(none)Auto-discover agent configs in the current directory + well-known global locations
--policy-file <path>Analyze an IAM policy JSON file
--role-arn <arn>Fetch + analyze a role's attached and inline policies (local AWS credentials)
--profile <name>Resolve a local AWS profile's identity and analyze it
--cfn-file <path>Scan a synthesized CloudFormation template for agent-like resources (Bedrock agent, ECS task definition, Lambda function) and their in-template IAM role

Auto-discovery paths

With no input flag, agent-scan walks these paths (project-level relative to the current directory, plus global/cross-project locations) looking for AWS_PROFILE, role ARNs, or hardcoded access keys:

PathScopeNotes
.mcp.json / mcp.jsonProjectAny OS
.claude/settings.json, .claude/settings.local.jsonProjectAny OS
.cursor/mcp.jsonProjectAny OS
.vscode/mcp.jsonProjectAny OS
~/.cursor/mcp.jsonGlobalAny OS
~/.codeium/windsurf/mcp_config.jsonGlobal (Windsurf)Any OS
.../Code/User/mcp.jsonGlobal (VS Code user profile)macOS / Windows / Linux paths
claude_desktop_config.jsonGlobal (Claude Desktop)macOS / Windows / Linux paths

How to read a blast-radius report

Every scan produces one overall grade — the worst finding wins:

GradeMeaning
CRITICALAt least one CRITICAL finding — the agent could take over the account or destroy production data.
HIGHAt least one HIGH finding, no CRITICAL — serious but bounded (e.g. can delete resources in one service).
MODERATEAt least one MEDIUM finding, nothing higher — worth tightening, not an emergency.
LOWOnly LOW findings or none — the credential is reasonably scoped.

Findings are grouped into six categories:

CategoryMeaning
DESTRUCTIVECan delete/terminate/modify infrastructure or data (S3, RDS, DynamoDB, EC2, ECS, Lambda, CloudFormation, Route53)
ESCALATIONCan grant itself (or others) more permissions (iam:PassRole, CreateAccessKey, AttachPolicy, sts:AssumeRole on *)
DATA_ACCESSCan read sensitive data stores (S3, Secrets Manager, SSM, RDS snapshots, DynamoDB)
COST_RISKCan run up the AWS bill without constraints (ec2:RunInstances, SageMaker, Bedrock InvokeModel)
WILDCARDStructurally unbounded grants (Action "*", service-wide wildcards, Resource "*", NotAction+Allow)
NO_GUARDRAILSMissing boundaries or hardcoded long-lived credentials in a config file

Each finding lists the matched actions, the affected resources, and a one-line fix — start with CRITICAL/HIGH findings in ESCALATION and DESTRUCTIVE first; those are the ones that turn a compromised or misbehaving agent into an account-wide incident.

Rule reference

Rules are matched by glob intersection (e.g. a grant of s3:* matches a rule for s3:DeleteObject) — no AWS action list is expanded or shipped.* marks rules whose severity is bumped when the statement's Resource is also "*". Suppress any rule with --ignore <rule-id>.

Rule IDCategorySeverityTitle
BR-DEST-S3DESTRUCTIVEHIGH / CRITICAL*Can delete or rewrite S3 data
BR-DEST-RDSDESTRUCTIVEHIGH / CRITICAL*Can delete or modify RDS databases
BR-DEST-DDBDESTRUCTIVEHIGH / CRITICAL*Can delete DynamoDB tables or items
BR-DEST-EC2DESTRUCTIVEHIGH / CRITICAL*Can terminate or modify EC2 instances
BR-DEST-ECSDESTRUCTIVEHIGH / CRITICAL*Can delete or modify ECS services
BR-DEST-LAMBDADESTRUCTIVEHIGH / CRITICAL*Can delete or rewrite Lambda functions
BR-DEST-CFNDESTRUCTIVEHIGH / CRITICAL*Can delete or mutate CloudFormation stacks
BR-DEST-R53DESTRUCTIVEHIGH / CRITICAL*Can change DNS records
BR-ESC-PASSROLEESCALATIONHIGH / CRITICAL*Can pass IAM roles to services
BR-ESC-CREATEKEYESCALATIONCRITICALCan mint credentials for other identities
BR-ESC-ATTACHESCALATIONCRITICALCan grant itself more permissions
BR-ESC-ASSUME-STARESCALATIONCRITICALCan assume any role in the account (sts:AssumeRole on *)
BR-DATA-S3DATA_ACCESSMEDIUM / HIGH*Can read S3 data
BR-DATA-SECRETSDATA_ACCESSHIGH / CRITICAL*Can read Secrets Manager secrets
BR-DATA-SSMDATA_ACCESSHIGH / CRITICAL*Can read SSM parameters
BR-DATA-RDS-SNAPDATA_ACCESSMEDIUM / HIGH*Can access RDS snapshots
BR-DATA-DDBDATA_ACCESSMEDIUM / HIGH*Can read DynamoDB data
BR-COST-EC2COST_RISKMEDIUM / HIGH*Can launch EC2 instances without constraints
BR-COST-SAGEMAKERCOST_RISKMEDIUM / HIGH*Can create SageMaker resources without constraints
BR-COST-BEDROCKCOST_RISKMEDIUM / HIGH*Can invoke Bedrock models without constraints
BR-WILD-ACTIONWILDCARDCRITICALAction "*" — unrestricted actions
BR-WILD-RESOURCEWILDCARDMEDIUMResource "*" — applies to every resource
BR-WILD-SERVICEWILDCARDHIGHService-wide wildcard action (e.g. s3:*)
BR-WILD-NOTACTIONWILDCARDHIGHAllow + NotAction — grants everything not listed
BR-GUARD-HARDCODED-KEYNO_GUARDRAILSCRITICALHardcoded AWS access key in agent config
BR-GUARD-NO-BOUNDARYNO_GUARDRAILSLOWNo permission boundary on the agent identity

Budget file reference (CI enforcement)

--budget shieldly.policy.yml declares the maximum permission budget an agent's credentials may have; agent-scan exits non-zero when a scan violates it — wire it into a PR check the same way you would a test suite.

# shieldly.policy.yml
maxSeverity: HIGH
denyCategories:
  - ESCALATION
ignoreRules:
  - BR-GUARD-NO-BOUNDARY
maxFindings: 10
FieldTypeMeaning
maxSeveritystringHighest severity allowed before the check fails: LOW | MEDIUM | HIGH | CRITICAL
denyCategoriesstring[]Fail if any finding falls in one of these categories (e.g. ESCALATION)
ignoreRulesstring[]Rule IDs to suppress, same as repeating --ignore <rule-id>
maxFindingsnumberFail if the total finding count exceeds this

YAML or JSON both work. See shieldly.policy.example.yml for a full example.

Use in CI

The Shieldly GitHub Action runs agent-scan directly — no API key needed, fully offline:

- name: Agent Blast-Radius
  uses: shieldly-io/action@v1
  with:
    agent-scan: true
    agent-scan-path: .
    budget-file: shieldly.policy.yml

See the GitHub Action docs for every input.

History, diffs & alerts (Builder plan+)

--upload sends the scan's findings (rule IDs, categories, severities, grade — never the policy document itself) to your Shieldly account: it builds a per-agent history, diffs each scan against the last one for that identity, and alerts Slack when a new CRITICAL finding appears. View it at /app/agents. Connected AWS accounts (Team plan+) also get a daily scheduled re-scan of their registered agent roles, so permission drift is caught even between manual scans.

FAQ

Does my agent config or policy ever leave my machine?

No. agent-scan runs fully offline — it never makes a network call unless you explicitly pass --upload with an API key, in which case only the finding metadata (rule IDs, categories, severities, counts) is sent, never the raw policy or config content.

Does agent-scan expand wildcard actions like s3:* into every matching AWS action?

No — it matches wildcard grants against rule patterns with glob intersection, so there's no AWS action list to ship, download, or go stale.

I got a false positive — how do I suppress just that rule?

Pass --ignore <rule-id> (repeatable), or add it to ignoreRules in your budget file. Think it's a bug in the rule itself? Open a false-positive report on the CLI's GitHub issues.

Does this replace IAM Access Analyzer?

No — they're complementary. Access Analyzer finds unused access across your whole account; agent-scan is agent-config-aware (it finds the credential an AI agent is actually using) and built for CI-native enforcement with a single command.