Skip to main content

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

Metadata

Release files for iamarmor 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for iamarmor 0.2.0
File Size Uploaded
iamarmor-0.2.0.tar.gz 43.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for iamarmor 0.2.0
File Interpreter ABI Platform
iamarmor-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 66.2 kB

Release files / iamarmor-0.2.0.tar.gz

Download URL iamarmor-0.2.0.tar.gz
Size 43.4 kB
Tags Source
SHA-256 checksum
How to use checksums
c01c17fab7bafe5524f3fef279d93d311304991b46ba76ad74570cd77a98d055
BLAKE2b-256 checksum
How to use checksums
3d8c1a3afc1f29124edbd2ccd8a25c5a9bdc5388f43acf8d5d54271322316d97
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 16, 2026.

Transparency log

Release files / iamarmor-0.2.0-py3-none-any.whl

Download URL iamarmor-0.2.0-py3-none-any.whl
Size 22.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e48ffc567215e9fd6e7a3aefe44348addc06a28fbc1a28fb29794311c40b5ddc
BLAKE2b-256 checksum
How to use checksums
495afaaa94f89542f3dc8af731ed6ba9496a8982fd87bdd20045d58efc2ba476
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page