The fastest way to ship an agent tool is AdministratorAccess “temporarily.” Six months later that role still deploys from CI and powers production sandboxes. AWS IAM Access Analyzer (external access + unused access findings) shows which principals can reach which resources and which actions have not been used — so you can shrink tool roles with evidence, not guesswork. Pair with Verified Permissions for per-tool authZ inside the app and GuardDuty / Detective when credentials are already on fire.
⚡ TL;DR: Enable organization-level Access Analyzer; turn on unused access analysis for agent accounts; filter findings by
workload=coding-agentroles; generate least-privilege policies from CloudTrail; apply in stages with canaries; alarm on new external-access findings. Related: CloudTrail Lake IAM abuses, Security Hub aggregation, IAM Roles Anywhere runners, Config Conformance Packs.
Threat model for agent roles
| Risk | Example | Analyzer angle |
|---|---|---|
| Over-broad resource ARNs | arn:aws:s3:::* for RAG |
Policy / external access findings |
| Unused powerful actions | iam:CreateUser never called |
Unused access findings |
| Cross-account trust | Confused-deputy tool role | External access analyzer |
| Long-lived keys on runners | Static keys on VM tools | Prefer Roles Anywhere; Analyzer + Credential Report |
❌ Treating Access Analyzer as a one-time audit — agent fleets churn weekly; findings must be continuous.
Enable analyzers (account and org)
# ✅ account-level external access analyzer
aws accessanalyzer create-analyzer \
--analyzer-name coding-agent-external \
--type ACCOUNT \
--tags Key=workload,Value=coding-agent
# ✅ unused access analyzer (where supported) — review unused permissions over a window
aws accessanalyzer create-analyzer \
--analyzer-name coding-agent-unused \
--type ACCOUNT_UNUSED_ACCESS \
--configuration '{
"unusedAccess": {"unusedAccessAge": 90}
}' \
--tags Key=workload,Value=coding-agent
For multi-account agent OUs, prefer organization analyzers from the delegated admin so sandboxes cannot “forget” to enable it.
Inventory agent roles and open findings
# ✅ list findings for a specific tool role
aws accessanalyzer list-findings \
--analyzer-arn arn:aws:access-analyzer:us-east-1:111122223333:analyzer/coding-agent-unused \
--filter '{
"resource": {"contains": ["role/coding-agent"]},
"status": {"eq": ["ACTIVE"]}
}'
# ✅ generate a tighter inline policy suggestion from recent CloudTrail (sketch)
# Prefer IAM Access Analyzer policy generation APIs / Console "Generate policy"
import boto3
aa = boto3.client("accessanalyzer")
resp = aa.start_policy_generation(
policyGenerationDetails={
"principalArn": "arn:aws:iam::111122223333:role/coding-agent-tool-sandbox"
},
cloudTrailDetails={
"trailArn": "arn:aws:cloudtrail:us-east-1:111122223333:trail/org",
"regions": ["us-east-1"],
"startTime": "2026-07-01T00:00:00Z",
},
)
print(resp["jobId"])
# poll get_generated_policy → review → attach as new managed policy → detach Admin
✅ Always review generated policies — CloudTrail-missing actions (rare cron paths) will be omitted. Keep a canary that exercises backup/restore tool paths before removing permissions.
Shrink roles without breaking sandboxes
- Tag every agent role
workload=coding-agent,tool=sandbox|rag|lint - Export unused actions with 90-day window
- Move to a new managed policy with removals; attach beside the old policy
- Run integration + FIS denial tests
- Detach the old fat policy
- Feed remaining gaps into Config packs so wildcards cannot return
// ✅ target shape for a sandbox tool role (illustrative least privilege)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SandboxArtifacts",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::coding-agent-artifacts-${AccountId}/*"
},
{
"Sid": "WriteLogs",
"Effect": "Allow",
"Action": ["logs:CreateLogStream", "logs:PutLogEvents"],
"Resource": "arn:aws:logs:*:*:log-group:/coding-agent/*"
}
]
}
❌ Resource: "*" with a short Action list “because the tool is trusted” — steal the session token and the Action list is the blast radius.
Wire findings into Security Hub and on-call
# ✅ Security Hub typically ingests Access Analyzer — confirm product enablement
aws securityhub get-findings \
--filters '{
"ProductName": [{"Value": "IAM Access Analyzer", "Comparison": "EQUALS"}],
"WorkflowStatus": [{"Value": "NEW", "Comparison": "EQUALS"}]
}' \
--max-results 20
Page on new external access findings for production agent roles immediately; batch unused-access cleanup weekly.
Production checklist
- [ ] Org or account analyzers enabled (external + unused)
- [ ] All agent roles tagged; fat policies named
*-breakglassif they must exist - [ ] Policy generation run per tool role after 2+ weeks of real traffic
- [ ] Canary covers rare actions before detachment
- [ ] New external findings → PagerDuty / Slack within minutes
- [ ] CloudTrail Lake queries retained for abuse forensics
- [ ] Roles Anywhere / OIDC preferred over static keys on runners
- [ ] Documented exception process with expiry dates
FAQ
Q: Analyzer vs SCPs?
A: SCPs set the ceiling. Analyzer shows how much of the remaining ceiling each role actually needs / exposes. You want both.
Q: Will unused access remove permissions automatically?
A: No — findings are advisory. You (or automation you write) must change policies. That is a feature for agent fleets.
Q: How does this relate to Verified Permissions?
A: IAM decides what AWS APIs the role may call. Cedar/Verified Permissions decides whether this user/session may invoke this tool. Different layers; do not collapse them.
Related reading
- CloudTrail Lake: Query Agent IAM Abuses
- AWS Security Hub: Aggregate Coding-Agent Security Findings
- AWS IAM Roles Anywhere: Cert Creds for On-Prem Runners
- AWS Verified Permissions: Cedar Authorize Agent Tools
Find the unused power, shrink with evidence, and make the next “temporary Admin” show up as a finding — not as a breach retrospective.
Last updated on October 2, 2026
Most viewed
- Python Decorators Explained: From Simple Wrappers to Production Patterns
- AI Agent Frameworks in 2025: LangGraph vs CrewAI vs AutoGen vs Raw API
- REST API Design Best Practices: The Patterns That Make APIs a Joy to Use
- Java Virtual Threads vs Traditional Threads: What Nobody Tells You
- Agentic Git Workflows: Atomic Commits From Noisy LLM Diffs
Newly added
- AWS IAM Access Analyzer: Find Over-Privileged Coding-Agent Roles Before They Leak
- Amazon CloudWatch Application Signals: SLOs and Traces for Multi-Hop Coding-Agent Tools
- AWS Config Conformance Packs: Continuous Compliance Guards for Coding-Agent Accounts
- Amazon Bedrock Provisioned Throughput: Reserved Capacity for Coding-Agent Latency SLOs
- AWS Lambda Response Streaming: Stream Coding-Agent Tokens Without Buffering Full Completions
Deep-dive PDF
Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.
Already subscribed? or open the subscribe page.
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.