Skip to main content

aws-compliance-as-code

Tests CodeQL OpenSSF Scorecard Release PyPI

Automated, repeatable compliance evidence for an AWS account, mapped to NIST 800-53, SOC 2, ISO 27001 and the CIS AWS Foundations Benchmark, and exported as OSCAL.

pip install "aws-compliance-as-code[demo]"
aws-compliance-as-code demo        # a fake, misconfigured account; no AWS needed

→ Read the sample report (no install needed): 15 controls run against a deliberately drifted sandbox account built with moto: root without MFA, a *:* break-glass policy, a single-region trail without log validation, partial S3 Block Public Access and more, each with hashed evidence and OSCAL.

Problem

Audit evidence is still mostly collected by hand. Someone logs into the console, takes screenshots of the IAM password policy, exports a CloudTrail config, pastes it into a spreadsheet, and repeats the whole thing next quarter for a different framework. It is slow, it only proves the state of the account on the day the screenshot was taken, nobody can tell whether a screenshot was edited, and the same AWS setting gets re-collected separately for SOC 2, ISO and NIST even though it is one fact.

How it works

controls.yaml ──> run.py ──> checks/*.py ──(read-only AWS API)──> evidence/<date>/<CONTROL>.json ──> oscal_export.py ──> oscal/assessment-results.json
  1. Control catalog. controls.yaml lists each control once, with a crosswalk to the requirement IDs it satisfies in four frameworks. Test once, satisfy many frameworks.
  2. Checks. Each control names a Python function in checks/ that takes a boto3 session, makes read-only API calls and returns PASS/FAIL, the findings, the API calls used and the raw API response, so an auditor can re-perform the test from the evidence alone.
  3. Hashed evidence. run.py writes one file per control to evidence/<YYYY-MM-DD>/<CONTROL-ID>.json with a timestamp, the account ID, the API call, the raw response and a SHA-256 of the raw response as canonical JSON (sorted keys, no spaces). Any edit to the raw data breaks the hash.
  4. OSCAL. oscal_export.py turns a day's evidence into an OSCAL 1.1.2 assessment-results document: one observation per control pointing at its evidence file and hash, and one finding per mapped NIST 800-53 control objective (satisfied / not-satisfied). Any GRC tool that reads OSCAL can ingest it.
  5. Tested offline. Every check has unit tests that run against AWS mocked with moto, covering both the compliant and non-compliant case. .github/workflows/tests.yml runs them on every push, so the project is verified without needing a live AWS account.

Controls covered

ID Control Check
IAM-01 Root account has MFA enabled check_root_mfa
IAM-02 Root account has no access keys check_root_access_keys
IAM-03 IAM password policy meets minimum strength check_password_policy
IAM-04 Access keys are rotated within 90 days check_access_key_age
IAM-05 Unused credentials are disabled check_unused_credentials
IAM-06 No policies grant full *:* administrative privileges check_no_wildcard_admin
LOG-01 CloudTrail is enabled in all regions check_cloudtrail_multi_region
LOG-02 CloudTrail log file validation is enabled check_cloudtrail_log_validation
DATA-01 S3 Block Public Access is enabled at the account level check_s3_account_public_access_block
DATA-02 S3 buckets have default encryption configured check_s3_default_encryption
DATA-03 EBS encryption by default is enabled check_ebs_default_encryption
DET-01 GuardDuty is enabled check_guardduty_enabled
DET-02 Security Hub is enabled check_securityhub_enabled
NET-01 VPC flow logs are enabled not implemented yet
CFG-01 AWS Config recorder is on not implemented yet

Framework versions: NIST SP 800-53 Rev. 5, AICPA TSC 2017 (rev. 2022), ISO/IEC 27001:2022 Annex A, CIS AWS Foundations v3.0.0. Mappings are my own judgment and should be checked against the official crosswalks before being relied on in a real audit.

Run it

Requirements: Python 3.11+, the AWS CLI v2, and a read-only profile (SecurityAudit + ReadOnlyAccess).

pip install aws-compliance-as-code
aws configure sso --profile pm
aws-compliance-as-code scan --profile pm          # PASS/FAIL table + evidence/<today>/*.json
aws-compliance-as-code oscal evidence/<today>     # oscal/assessment-results.json

From a clone, python run.py --profile pm and python oscal_export.py still work, and pytest -q runs every check offline against mocked AWS (moto).

No AWS account? aws-compliance-as-code demo (with the [demo] extra) builds a misconfigured fake account and runs every check against it.

What I'd do at enterprise scale

  • Run it continuously. Schedule it in CI with short-lived OIDC credentials (no stored AWS keys) and commit each day's evidence, giving a dated, version-controlled evidence history.
  • Many accounts, one run. Run from a security tooling account and assume a read-only audit role in every member account through AWS Organizations, so one nightly job covers hundreds of accounts.
  • Lean on native services. Use AWS Config conformance packs and Security Hub's CIS/NIST standards for continuous detection, and keep this pipeline for what auditors actually need: evidence tied to framework requirements, in OSCAL.
  • Make evidence tamper-evident beyond the hash. Write evidence to an S3 bucket with Object Lock (WORM) in a separate account, and sign each file or chain the hashes so editing evidence also needs access the editor doesn't have.
  • Close the loop. Turn not-satisfied findings into OSCAL POA&M items and tickets with owners and due dates, and track exceptions with expiry dates instead of letting them live forever.
  • Govern the catalog. Version controls.yaml with reviews from compliance, security and the control owners, and validate OSCAL output against the official NIST schemas in CI.

Safety

Every check is read-only and only needs the SecurityAudit / ReadOnlyAccess managed policies. No credentials are stored in this repo. If you run it against a real account, note that evidence files contain the account ID and IAM user names, so keep evidence/ out of public repos.

Metadata

Release files for aws-compliance-as-code 1.1.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 aws-compliance-as-code 1.1.0
File Size Uploaded Provenance Actions
aws_compliance_as_code-1.1.0.tar.gz 20.7 kB With provenance Details for aws_compliance_as_code-1.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for aws-compliance-as-code 1.1.0
File Interpreter ABI Platform Actions
aws_compliance_as_code-1.1.0-py3-none-any.whl Python 3 none any Details for aws_compliance_as_code-1.1.0-py3-none-any.whl

Total release size: 39.6 kB

Release files / aws_compliance_as_code-1.1.0.tar.gz

Download URL aws_compliance_as_code-1.1.0.tar.gz
Size 20.7 kB
Tags Source
SHA-256 checksum
How to use checksums
8d7b69b518456a63bd2164f19894954fbe38ecbea4c098f82fa2e207619b37cb
BLAKE2b-256 checksum
How to use checksums
15612af3b59d3aefc4dcd40b72dd28487c6dab9276b75b71036e3ebe1ff2dc70
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 22, 2026.

Transparency log

Release files / aws_compliance_as_code-1.1.0-py3-none-any.whl

Download URL aws_compliance_as_code-1.1.0-py3-none-any.whl
Size 19.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
39694d8a8883312c8f8099ab79df5ff845c7d62e48be308d7afe20de29e8615b
BLAKE2b-256 checksum
How to use checksums
2a20f8d5a71cbfddc4a0a9d20a5b570b8d96ce3bdfce58e89ceb8da6b52fb6fd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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 Oct 22, 2026.

Transparency log

Security for aws-compliance-as-code 1.1.0

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for aws_compliance_as_code-1.1.0.tar.gz

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 Oct 22, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files Full provenance

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