Skip to main content
>_ supraj.dev
SECURITY · AI

IAM Drift Sentinel

Every over-permissive IAM policy starts as a shortcut under deadline pressure. This loop catches the shortcut in real time, reasons about what the role actually uses, and hands you a scoped replacement as a reviewable PR. It never merges anything itself.

TRIGGER
CloudTrail: PutRolePolicy / AttachRolePolicy
GATE
policy grants *:*, NotAction, or crosses account boundary
REASON · AI
classify blast radius against 90 days of Access Analyzer data
VERIFY
proposed policy replayed in IAM simulator — zero broken calls
ACT
Terraform PR with scoped policy + diff to #sec-alerts
01 — INSTALL
brew install supraj/tap/iam-sentinel
iam-sentinel init --account 8842-xxxx --region ap-south-1
02 — CONFIGURE

One YAML file per account. The gate keeps noise out; the escalation rule keeps the AI honest.

# sentinel.yaml
trigger:
  source: cloudtrail
  events: [PutRolePolicy, AttachRolePolicy]
gate:
  match: ["Action: '*'", "NotAction", "cross-account"]
reason:
  model: claude-sonnet
  context: access-analyzer:90d
  on_low_confidence: escalate   # never guess
act:
  pr: terraform/iam/
  notify: '#sec-alerts'
03 — HOW IT WORKS
01
Deploy once per AWS account. The sentinel subscribes to CloudTrail via EventBridge — no agents, no polling.
02
When a risky policy lands, it pulls what the role actually did over 90 days and drafts the minimum policy that keeps every real call working.
03
The draft is replayed through the IAM policy simulator. Only a clean replay produces a PR — anything ambiguous escalates to a human with full context.
04 — EXAMPLE OUTPUT
$ iam-sentinel status
● watching 3 accounts · last event 2m ago

[Jul 06 11:42] PutRolePolicy on role/ci-deployer
  gate: matched  Action:'*' on s3
  reason: role used 4 of 214 granted actions (90d)
  verify: simulator replay OK — 0 broken calls
  act: PR #312 opened → terraform/iam/ci-deployer.tf