Skip to main content

IAM Policy Analyzer & Fixer

Project description

iamarmor

A static analyzer for AWS IAM policies in Terraform — catch over-permissioned policies before they merge.

PyPI version Python versions CI License: MIT


Why iam-armor?

IAM misconfigurations are the #1 cause of AWS breaches — wildcards on Action and Resource, forgotten AdministratorAccess attachments, and overly-permissive assume_role_policy are easy to ship and hard to spot in code review.

iamarmor is a static analyzer for Terraform IAM resources. It runs entirely offline — no AWS credentials and no terraform plan required — and fits cleanly into your workflow as a pre-commit hook or CI step.

$ iamarmor scan modules/iam/

  modules/iam/main.tf
  ✘ IAM001 [HIGH]   resource 'aws_iam_policy.app' has Action: "*" — grant least-privilege actions instead.
  ✘ IAM005 [HIGH]   resource 'aws_iam_policy.deployer' grants iam:PassRole on Resource: "*" — scope to specific role ARNs.
  ✘ IAM010 [HIGH]   resource 'aws_iam_role_policy_attachment.admin' attaches AdministratorAccess — grant only required permissions.

  3 findings  (3 high, 0 medium, 0 low)  in 0.12 s
  exit 1

Demo

iamarmor demo

Regenerate with: vhs docs/demo.tape


Quickstart

# Install (requires Python 3.11+)
pip install iamarmor

# Scan the current directory
iamarmor scan .

# Scan a specific file
iamarmor scan modules/iam/main.tf

# Machine-readable output for CI pipelines
iamarmor scan . --format json

iamarmor scan exits 0 when clean, 1 when findings meet the fail_on threshold (default: medium), 2 on usage/config errors, and 3 on internal errors — making CI integration trivial.


Configuration

Place a .iamarmor.yml in the root of your Terraform repository:

version: 1
severity_threshold: low   # report findings at or above this level (default: info)
fail_on: high             # exit 1 only for high/critical (default: medium)

rules:
  ignore: [IAM004]        # skip noisy rules for your environment
  overrides:
    IAM002:
      severity: critical  # escalate a rule's severity

paths:
  exclude:
    - "modules/legacy/**"  # skip paths you're not ready to fix yet

iamarmor auto-discovers .iamarmor.yml by walking upward from the target path. Pass --no-config to skip loading.

See docs/config.md for the full configuration reference.


Default rule pack

iamarmor ships with 10 default IAM rules covering the most common misconfigurations:

ID Name Severity
IAM001 No Action: "*" High
IAM002 No Resource: "*" with sensitive actions High
IAM003 No inline policies Medium
IAM004 IAM roles must set max_session_duration Low
IAM005 No iam:PassRole with Resource: "*" High
IAM006 No wildcard Principal in resource-based policies High
IAM007 assume_role_policy must specify a concrete principal High
IAM008 No NotAction in Allow statements Medium
IAM009 No NotResource in Allow statements Medium
IAM010 Do not attach AdministratorAccess managed policy High

See STARTER_RULES.md for full documentation of each rule, including rationale, examples, and configuration options.


Pre-commit hook

Add to your .pre-commit-config.yaml:

repos:
  - repo: https://github.com/iam-armor/iamarmor
    rev: v0.2.0
    hooks:
      - id: iamarmor

See docs/pre-commit.md for details.


GitHub Actions CI

Add to your workflow to scan Terraform in every PR:

- name: Scan IAM policies
  run: |
    pip install iamarmor
    iamarmor scan . --fail-on high

Or pin a specific version:

- name: Scan IAM policies
  run: |
    pip install iamarmor==0.2.0
    iamarmor scan modules/iam/ --format json > iam-findings.json

Python API

The CLI is the recommended entry point for most users. For embedding iamarmor in other tools, the Python API is also public:

from iamarmor import extract_from_directory, RuleEngine, load_default_rules

resources = extract_from_directory("path/to/terraform/")
engine = RuleEngine(rules=load_default_rules())
findings = engine.run(resources)

for finding in findings:
    print(f"[{finding.rule_id}] {finding.severity.value.upper()}{finding.message}")

Regenerating the demo GIF

The demo GIF was recorded with VHS. To regenerate it:

# Install VHS (requires Go)
go install github.com/charmbracelet/vhs@latest

# Re-record
vhs docs/demo.tape

The resulting docs/demo.gif is committed to the repository. The tape script exercises iamarmor scan against the bundled tests/fixtures/ directory.


Roadmap

iamarmor (this repo) is the OSS static analyzer engine. The hosted GitHub App at iamarmor.dev (coming soon) will add:

  • 🔌 GitHub App with inline PR annotations
  • 📦 Premium rule packs: SOC 2, PCI-DSS, HIPAA, AWS Well-Architected Security
  • 📊 Findings dashboard and trend tracking
  • 🔧 One-click auto-fix suggestions

Contributing

Contributions are welcome! Please open an issue before submitting a PR for new features or rules. See STARTER_RULES.md for the existing rule inventory and docs/ for design docs.

git clone https://github.com/iam-armor/iamarmor.git
cd iamarmor
pip install -e ".[dev]"
pytest
ruff check src/ tests/

License

MIT © 2026 iam-armor

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

iamarmor-0.2.0.tar.gz (43.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

iamarmor-0.2.0-py3-none-any.whl (22.8 kB view details)

Uploaded Python 3

File details

Details for the file iamarmor-0.2.0.tar.gz.

File metadata

  • Download URL: iamarmor-0.2.0.tar.gz
  • Upload date:
  • Size: 43.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for iamarmor-0.2.0.tar.gz
Algorithm Hash digest
SHA256 c01c17fab7bafe5524f3fef279d93d311304991b46ba76ad74570cd77a98d055
MD5 ab3641277e01b8e5b3f00761275922aa
BLAKE2b-256 3d8c1a3afc1f29124edbd2ccd8a25c5a9bdc5388f43acf8d5d54271322316d97

See more details on using hashes here.

Provenance

The following attestation bundles were made for iamarmor-0.2.0.tar.gz:

Publisher: publish.yml on iam-armor/iamarmor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file iamarmor-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: iamarmor-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 22.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for iamarmor-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e48ffc567215e9fd6e7a3aefe44348addc06a28fbc1a28fb29794311c40b5ddc
MD5 8e6ab9288ef9d5ff716c133aee5b53db
BLAKE2b-256 495afaaa94f89542f3dc8af731ed6ba9496a8982fd87bdd20045d58efc2ba476

See more details on using hashes here.

Provenance

The following attestation bundles were made for iamarmor-0.2.0-py3-none-any.whl:

Publisher: publish.yml on iam-armor/iamarmor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page