Skip to main content

audit-report

License: GPL v3 Python

Turns an audit-tools evidence package into a control-mapped, auditor-ready report — Markdown, self-contained HTML, or JSON — driven by declarative rulesets.

audit-tools collects raw CSVs (IAM users, branch protections, security groups…). audit-report reads that package, applies pass/fail rules, maps each result to SOC 2, ISO 27001, and NIST SP 800-53 controls, and produces a report you can hand to an auditor or gate a pipeline on.

Like gh-attest, this tool produces evidence, not a compliance verdict. A failing row means a setting is in a state that does not support a control; the final judgment belongs to the organization and its auditor.

Install

pip install audit-report

To hack on it from a clone instead, see Development.

Usage

Point it at a package directory produced by audit-tools:

# Markdown report to stdout (platform + ruleset auto-detected from the dir name)
audit-report ./output/aws_audit_default_2026-07-29

# All three formats into ./report/
audit-report ./output/github_audit_acme_2026-07-29 --format md,html,json --out report/

# Gate CI: exit non-zero if any high-severity check fails
audit-report ./output/aws_audit_prod_2026-07-29 --fail-on high --out report/

Diff mode — compare two packages

Pass --baseline to report how a package drifted from an earlier one. Both are evaluated with the same ruleset; the report classifies each rule as regressed, fixed, drifted (an ongoing failure whose evidence rows changed), changed, or unchanged — and shows exactly which evidence rows appeared or disappeared.

# How did prod change between two audit runs?
audit-report ./output/aws_audit_prod_2026-07-29 \
  --baseline ./output/aws_audit_prod_2026-06-29 \
  --format md,html --out drift/

# Fail CI if this change regressed any high-severity control
audit-report ./output/aws_audit_prod_2026-07-29 \
  --baseline ./output/aws_audit_prod_2026-06-29 --fail-on high

In diff mode --fail-on gates on regressions at or above the given severity, and output files are named diff.* instead of report.*.

Trend mode — track controls over time

Pass --trend and point at a folder of dated packages (for example audit-tools' output/). Every package in the series is evaluated with the same ruleset and laid out as a timeline — one row per rule, one column per date — so you can watch a control drift in and out of compliance.

# Heatmap of every control across all retained prod packages
audit-report ./output --trend --format html,json --out trend/

# Disambiguate when the folder holds more than one series
audit-report ./output --trend --subject prod --out trend/

The series must share one platform and subject (use --subject to pick one) and contain at least two packages. In trend mode --fail-on reflects the latest package, so it can double as a snapshot gate. Output files are named trend.*.

You can also run it without installing:

python -m audit_report ./output/aws_audit_default_2026-07-29

Options

Flag Description
--baseline PATH Diff mode: report how PACKAGE drifted from this earlier package.
--trend Trend mode: treat PACKAGE as a folder of dated packages and chart each rule over time.
--subject NAME In trend mode, pick one subject when the folder holds several series.
--ruleset PATH Use a specific ruleset instead of the bundled one for the detected platform.
--format md,html,json One or more output formats (default: md).
--out DIR Write report.<ext> files into DIR. Without it, the first format prints to stdout.
--fail-on low|medium|high|none Exit non-zero when a failing finding — or, in diff mode, a regression — meets this severity (default: none).

What a report contains

  • Summary — failing / passing / not-applicable counts.
  • Control coverage matrix — every cited control, its framework, and a worst-wins status rolled up from the rules that reference it. One failing rule marks the control as not fully evidenced.
  • Findings — failures first, then by severity, each with the reason, why it matters, remediation, and the exact evidence rows that failed.

Bundled rulesets

Platform Package prefix Checks include
AWS aws_audit_* Console-user MFA, access-key rotation, root MFA & keys, password policy, open SSH, public S3, CloudTrail logging
GitHub github_audit_* Org 2FA, base permission, secret-scanning push protection, default-branch protection, required reviews
GitLab gitlab_audit_* Force-push on protected branches, code-owner approval, approval-rule strength, public projects, instance password policy, audit logging

Writing your own rules

A ruleset is a YAML file: a platform and a list of rules. Each rule names a CSV table, a check, the controls it maps to, and human-readable text. Point at one with --ruleset.

platform: aws
rules:
  - id: aws.iam.console-mfa
    title: Console users have MFA enabled
    table: iam_users            # <table>.csv inside the package
    severity: high              # high | medium | low
    controls: [SOC2:CC6.1, ISO:A.5.17, NIST:IA-2]
    rationale: A console user without a second factor is one stolen password from access.
    remediation: Enforce MFA for all console users, or remove their console password.
    check:
      type: fail_rows_where     # every matching row is a failure
      when:
        all:
          - {column: console_password, op: is_true}
          - {column: mfa_enabled, op: is_false}

Check types

Type Meaning
fail_rows_where Each row matching when is a failing finding.
fail_if_any_rows The presence of any row (optionally filtered by when) is a failure.
require_any_row Passes only if at least one row satisfies when.
assert_row Checks each condition in require against the first row of a single-row config table.

Condition language — a condition is a leaf {column, op, value}, or one of {all: [...]}, {any: [...]}, {not: ...}. Operators: equals, not_equals, is_true, is_false, in, not_in, gt, gte, lt, lte, empty, not_empty. Control codes referenced by a rule must exist in audit_report/catalog.py.

Continuous integration

Run it on a schedule or in a pipeline to keep evidence current and gate on regressions. See docs/ci.md and the ready-to-copy examples:

The --fail-on exit code (1 = a finding/regression met the threshold, 2 = usage error) lets a workflow separate "the audit found a problem" from "the job is misconfigured".

Stability

audit-report is stable as of v1.0.0 and follows semantic versioning. The JSON report schema — findings carrying their controls and pass / fail / not_applicable status — is a committed contract that control-coverage consumes directly; it will not break without a major-version bump.

Development

pip install -e ".[dev]"
pytest        # run from the project root
ruff check .

License

GPL-3.0-or-later. See LICENSE.

Metadata

Release files for audit-report 1.0.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 audit-report 1.0.0
File Size Uploaded
audit_report-1.0.0.tar.gz 47.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for audit-report 1.0.0
File Interpreter ABI Platform
audit_report-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 94.3 kB

Release files / audit_report-1.0.0.tar.gz

Download URL audit_report-1.0.0.tar.gz
Size 47.3 kB
Tags Source
SHA-256 checksum
How to use checksums
d832cc41bb56ca008a9b98550564c01a0f4b49371bff47a7d35312a5794700bd
BLAKE2b-256 checksum
How to use checksums
366af7769538db24ed2a4e8cfbcb25e0f8ac69b84ecc4ed4ea03c3cb7c861c1f
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 Aug 8, 2026.

Transparency log

Release files / audit_report-1.0.0-py3-none-any.whl

Download URL audit_report-1.0.0-py3-none-any.whl
Size 47.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c26087591b7997e021ee44e9c84bff6a071e27b3ae4cbaf0de08dd7bec11cd19
BLAKE2b-256 checksum
How to use checksums
13a4c43ba78b68e22290710e1640837bb1ee150c58bcc8490434426419872520
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 Aug 8, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.1.0

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