cloud-iam-auditor-pb
A lightweight, offline CLI that audits exported AWS and GCP IAM JSON policies for zero-trust violations and maps every finding to NIST 800-53, NIST 800-207, CIS Foundations (AWS / GCP), and MITRE ATT&CK Enterprise.
cloud-iam-auditor-pb is a deterministic, no-credential-required security scanner. It does not call AWS or GCP - it parses IAM policy documents you export and flags over-permissive patterns that violate least-privilege and zero-trust principles.
Table of contents
- Why this exists
- Install
- Quickstart
- CLI reference
- Detection rules
- Framework mappings
- CI/CD integration
- Supported inputs
- What v0.2.0 does not do
- Roadmap
- Development
- License
Why this exists
Startups scale fast. Developers reach for AdministratorAccess, Action: "*" or roles/owner to ship, creating security debt invisible until a breach. cloud-iam-auditor-pb lets an engineer drop a JSON file and answer:
Is this IAM role stuck in zero-trust debt? Which NIST / MITRE / CIS controls does it violate, and how do I fix it?
in under one second, in their terminal or in CI.
Multi-cloud teams benefit further: the same iam-audit binary handles both AWS IAM statements and GCP IAM role bindings, so a single CI gate keeps debt out of either cloud.
Install
pip install cloud-iam-auditor-pb
Requires Python >= 3.8. Works on Linux, macOS, and Windows.
Quickstart
Provider is auto-detected from the JSON shape:
| Top-level JSON key | Detected provider | Rule set used |
|---|---|---|
Statement (or PolicyDocument) |
AWS | 10 AWS rules |
bindings |
GCP | 5 GCP rules |
AWS
iam-audit scan examples/sample_aws_policy.json
Machine-readable output for CI:
iam-audit scan iam/release-role.json --json --severity high --exit-code
GCP
Export a project's IAM policy with:
gcloud projects get-iam-policy PROJECT_ID --format=json > iam/project_bindings.json
Then:
iam-audit scan iam/project_bindings.json
The CLI will print Detected GCP IAM policy... and run the 5 GCP rules against the bindings array.
CLI reference
iam-audit --version
iam-audit scan PATH [--json] [--severity LEVEL] [--exit-code] [--no-color]
iam-audit rules [--json]
| Flag | Purpose |
|---|---|
--json |
Emit machine-readable JSON instead of a Rich table. |
--severity {low,medium,high,critical} |
Only report findings at or above the threshold. |
--exit-code |
Exit non-zero (1) when any finding remains - perfect for CI gates. |
--no-color |
Disable ANSI styling (accessibility / logs). |
Status line ("Detected AWS/GCP IAM policy...") is written to stderr, so JSON pipes consuming stdout stay clean.
Detection rules
There are 15 rules total (10 AWS + 5 GCP). Each is implemented as a single class in its own module, registered with the provider-specific registry, and accompanied by a passing and failing fixture in tests/fixtures/.
Run iam-audit rules to get the same table in your terminal.
AWS rules (10)
| ID | Rule | Severity | Map |
|---|---|---|---|
| IAM001 | Action: "*" on Allow |
Critical | NIST AC-6 / CIS 1.16 / MITRE T1078.004 |
| IAM002 | Resource: "*" with broad Action set |
High | NIST AC-6 / ZT 3.2.1 / CIS 1.16 |
| IAM003 | AWS-managed AdministratorAccess attached |
Critical | NIST AC-6(5) / CIS 1.16 / MITRE T1078.004 |
| IAM004 | iam:PassRole against "*" |
High | NIST AC-3 / MITRE T1078.004 |
| IAM005 | Sensitive action with no Condition block |
Medium | NIST IA-2(1) / CIS 1.4 / MITRE T1098 |
| IAM006 | NotAction used with Allow |
High | NIST AC-6 / CIS 1.16 |
| IAM007 | NotResource used with Allow |
Medium | NIST AC-6 / CIS 1.16 |
| IAM008 | sts:AssumeRole against "*" (no trust condition) |
High | NIST AC-6 / MITRE T1550.001 |
| IAM009 | kms:Decrypt against wildcard resource |
High | NIST SC-12 / CIS 2.8 |
| IAM010 | s3:PutObject against arn:aws:s3:::*/* |
Medium | NIST SC-28 / CIS 2.1.5 |
GCP rules (5)
| ID | Rule | Severity | Map |
|---|---|---|---|
| GCP001 | Privileged role (owner/editor/*admin*) granted to allUsers / allAuthenticatedUsers |
Critical | CIS GCP 1.4 / 1.5 / MITRE T1078.004 |
| GCP002 | Any role granted to public members (non-privileged - intentional access check) | High | CIS GCP 1.10 / MITRE T1078.004 |
| GCP003 | roles/iam.serviceAccountUser granted to >3 principals (SA impersonation blast radius) |
Medium | NIST AC-6 / MITRE T1098 |
| GCP004 | Legacy primitive role (owner/editor/viewer) granted to a principal |
High | CIS GCP 1.3 / NIST AC-6(5) / MITRE T1078.004 |
| GCP005 | roles/iam.serviceAccountTokenCreator granted to >2 principals (OAuth token-mint blast radius) |
High | NIST AC-6 / MITRE T1550.001 / T1098 |
Framework mappings
Every finding ships with one or more framework references that the reporter renders inline. The full mapping table lives in cloud_iam_auditor/frameworks.py and covers:
- NIST SP 800-53 Rev. 5 (e.g. AC-6, AC-6(5), AC-6(7), AC-3, SC-12, SC-28, IA-2, IA-2(1))
- NIST SP 800-207 Zero Trust Architecture
- CIS AWS Foundations Benchmark v3.0 (1.4, 1.16, 2.1.5, 2.8)
- CIS GCP Foundations Benchmark v3.0 (1.3, 1.4, 1.5, 1.10)
- MITRE ATT&CK Enterprise (T1078, T1078.004, T1098, T1556, T1550, T1550.001)
CI/CD integration
Drop this step into any GitHub Actions job after you check out the policy file:
- run: pip install cloud-iam-auditor-pb
- run: iam-audit scan iam/release-role.json --json --exit-code --severity high
The job will fail (exit 1) if any High or Critical finding exists. The same workflow supports GCP bindings:
- run: gcloud projects get-iam-policy ${{ vars.PROJECT_ID }} --format=json > iam/bindings.json
- run: iam-audit scan iam/bindings.json --json --exit-code --severity high
Supported inputs
| Provider | Accepted shapes |
|---|---|
| AWS | Bare policy: {"Version": "...", "Statement": [...]} Wrapped aws iam get-policy-version response: {"PolicyDocument": {...}, "PolicyName": "..."} Single statement or array - both normalized. |
| GCP | {"bindings": [{"role": "roles/...", "members": [...]}, ...]} (output of gcloud projects get-iam-policy). Each binding must contain role and members. |
The loader raises a clear LoaderError describing the expected shape on any failure with exit code 2.
What v0.2.0 does not do (by design)
- No cloud credentials. v0.2.0 is a static JSON audit; it never calls AWS or GCP.
- Live AWS / GCP mode (boto3 / google-cloud-iam) is on the v0.3.0 roadmap.
- Azure RBAC support is on the v0.3.0 roadmap.
- SARIF output (for GitHub Code Scanning) is on the v0.3.0 roadmap.
This scoping keeps v0.2.0 auditable, dependency-light, and CI-friendly.
Roadmap
See CHANGELOG.md for the planned v0.3.0 work.
Development
git clone https://github.com/purvanshbhatt/cloud-iam-auditor
cd cloud-iam-auditor
python -m venv .venv
.venv\Scripts\activate # Windows
# source .venv/bin/activate # macOS/Linux
pip install -e ".[dev]"
pytest -q # 57 tests across AWS + GCP
ruff check .
python -m build # produce wheel + sdist in dist/
License
MIT - (c) 2026 Purvansh Bhatt.
Metadata
Release files for cloud-iam-auditor-pb 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cloud_iam_auditor_pb-0.3.0.tar.gz | 49.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cloud_iam_auditor_pb-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 107.9 kB
Release files / cloud_iam_auditor_pb-0.3.0.tar.gz
| Download URL | cloud_iam_auditor_pb-0.3.0.tar.gz |
|---|---|
| Size | 49.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
aa2ed37d8e9a59e323745e213b58b6c57a92f11c833121839f6801144f8b8262
|
|
BLAKE2b-256 checksum How to use checksums |
32078854f417fc28ea9290f1cef04a0d1e82f659f0d472759b170876ba7b8872
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.3
|
Release files / cloud_iam_auditor_pb-0.3.0-py3-none-any.whl
| Download URL | cloud_iam_auditor_pb-0.3.0-py3-none-any.whl |
|---|---|
| Size | 58.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3412db3ad10ac8f0901df2862a90bb93dabddf93dfe85a2ef82456a3a291fb76
|
|
BLAKE2b-256 checksum How to use checksums |
f07e9b2fc948adffc77d16e4e2ecdd1910bfc37f9462c362da60bfe4473560a0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.3
|