Detect overpermissive IAM roles on AWS + GCP and auto-open PRs with least-privilege policies
Project description
iam-zero ⚡
Detect overpermissive IAM roles on AWS and GCP. Auto-generate least-privilege policies. Open PRs — not tickets.
Most IAM roles are massively over-permissioned. Teams either handcraft policies (slow, error-prone) or attach AdministratorAccess and pray. Neither scales.
iam-zero reads your actual audit logs — CloudTrail for AWS, Cloud Audit Logs for GCP — figures out what permissions a role actually uses, and opens a GitHub PR with a tightened policy. A human reviews before anything changes.
No agents writing IAM policies directly. No surprises. Everything goes through code review.
How it works
CloudTrail / Cloud Audit Logs
↓
What did this role actually call in the last 90 days?
↓
Claude reasons: safe to remove vs. risky
↓
Minimal policy generated
↓
PR opened with before/after diff
Quickstart
# 1. Install
pip install zero-iam
# 2. Configure (just your Anthropic key)
iam-zero configure
# 3. Enable GCP APIs (one-time, only if scanning GCP)
gcloud services enable \
cloudresourcemanager.googleapis.com \
logging.googleapis.com \
iam.googleapis.com \
--project YOUR-PROJECT
# 4. Scan an AWS role — dry run by default, zero side effects
iam-zero scan aws --role arn:aws:iam::123456789012:role/my-role
# Or scan a GCP service account
iam-zero scan gcp \
--service-account sa@my-project.iam.gserviceaccount.com \
--project my-project
Output modes
| Command | What happens |
|---|---|
iam-zero scan aws --role <arn> |
Dry run — findings printed to terminal, nothing written |
iam-zero scan aws --all-roles |
Scan every IAM role in the account |
iam-zero scan gcp --service-account <sa> --project <p> |
Single GCP service account (dry run) |
iam-zero scan gcp --all-service-accounts --project <p> |
Scan every SA in the project |
iam-zero scan aws --role <arn> --output policy.json |
Writes recommended policy to a file |
iam-zero scan aws --role <arn> --github |
Opens a GitHub PR with full before/after diff |
iam-zero scan aws --role <arn> --output policy.json --github |
Both file + PR |
iam-zero scan aws --role <arn> --region us-east-2 |
Specify CloudTrail region (AWS only) |
iam-zero scan aws --role <arn> --no-access-advisor |
Skip Access Advisor corroboration (AWS only, not recommended) |
--dry-run always takes priority. Safe by default.
What the output looks like
╭──────────────────────────────────────────────╮
│ iam-zero ⚡ IAM Least-Privilege Scanner │
╰──────────────────────────────────────────────╯
Provider GCP
Identity terraform-review-sa@my-project.iam.gserviceaccount.com
Project my-project
Lookback 90 days
Mode dry-run
✓ Fetching IAM role bindings [4 roles]
✓ Reading Cloud Audit Logs [1,204 unique methods]
✓ Claude analysis complete
Permission Last Seen Risk Recommendation
───────────────────────────────────────────────────────────────
roles/editor Never HIGH ✋ Keep (risky)
roles/storage.objectAdmin Never LOW ✂ Remove
roles/logging.viewer Never LOW ✂ Remove
roles/iam.serviceAccountUser 3 days ago — ✓ Keep (active)
╭─ Summary ────────────────────────────────╮
│ 2 permissions safe to remove │
│ 1 flagged for manual review │
│ 1 active — kept untouched │
│ │
│ Blast radius reduction: 50% │
╰──────────────────────────────────────────╯
Required permissions
AWS (your caller identity)
cloudtrail:LookupEventsiam:GenerateServiceLastAccessedDetailsiam:GetServiceLastAccessedDetailsiam:GetRoleiam:ListAttachedRolePoliciesiam:GetPolicyiam:GetPolicyVersioniam:ListRolePoliciesiam:GetRolePolicy
GCP (your caller identity)
resourcemanager.projects.getIamPolicylogging.logEntries.list
Safety guarantees
- Read-only — never modifies IAM policies directly
- Dry run by default — zero side effects unless you pass
--outputor--github - Human in the loop — all changes go through a PR before anything is applied
- Idempotent — won't open a duplicate PR if one already exists for this identity
- PRs carry the artifact — the recommended policy is committed as
iam-zero/<cloud>/<identity>.recommended-policy.jsonon the PR branch, so merging puts the policy in your repo for your IaC pipeline to pick up
Known limitations (read before trusting output)
- CloudTrail
LookupEventsrecords management events only. Data-plane calls (s3:GetObject,dynamodb:GetItem,sqs:SendMessage, ...) never appear there. iam-zero corroborates with IAM Access Advisor: any action whose service shows recent authentication is automatically protected from a "remove" recommendation. Access Advisor is service-granular, not action-granular — treat every removal as a hypothesis and test in staging first. - CloudTrail lookup is per-region. Pass
--regionfor each region the role is active in, or activity outside your default region will be missed. - GCP Data Access audit logs are disabled by default. If they're off, read-heavy usage (GCS reads, BigQuery queries) is invisible; iam-zero's prompt biases toward "investigate" for such roles, but enable Data Access logs for real signal.
- CloudTrail
LookupEventsretains 90 days.--daysbeyond 90 won't return more.
Development
git clone https://github.com/MaripeddiSupraj/iam-zero
cd iam-zero
pip install -e ".[dev]"
pytest # 57 tests, all pass
Roadmap
- GCP service account scanning
- AWS IAM role scanning
- Claude-powered safe-removal analysis
- GitHub PR output
-
--all-roles/--all-service-accountsbulk scanning - Homebrew install
- CI exit code for policy drift detection
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file zero_iam-0.2.0.tar.gz.
File metadata
- Download URL: zero_iam-0.2.0.tar.gz
- Upload date:
- Size: 30.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c27fd655c2d22e153c31004d0254b8101643d5480957b04b7f06c579effe19c9
|
|
| MD5 |
d67d540689c2e9a55ac520120a50fd41
|
|
| BLAKE2b-256 |
07e54bb854e2fe71f4828d6d8de54dc36af43bf15b343aece80ee6e8fc60b684
|
File details
Details for the file zero_iam-0.2.0-py3-none-any.whl.
File metadata
- Download URL: zero_iam-0.2.0-py3-none-any.whl
- Upload date:
- Size: 28.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
70bb6ff3633801762aff3de5f91becc05881e9f438d6293f58514e7935bee1af
|
|
| MD5 |
44f48d121975fabdcb9538a125ad2f55
|
|
| BLAKE2b-256 |
79079548633e5515a767fac0eb28a25da15d4b9479f16c8c9b9366239b1997b7
|