audit-labs/audit-report

Turn audit-tools evidence packages into control-mapped, auditor-ready reports.

clone: git clone https://gitbay.org/audit-labs/audit-report.git

v1.0.0: audit_report/rulesets/aws.yaml · raw

  1# Ruleset: AWS
  2#
  3# Evaluated against an audit-tools AWS evidence package
  4# (aws_audit_<profile>_<date>/). Each rule names a CSV table, a check, and the
  5# controls the signal is offered as evidence for. A "fail" means a setting is in
  6# a state that does NOT support the control — an auditor still owns the verdict.
  7#
  8# Provenance and control-mapping rationale: see MAPPING.md. Bump `version` on any
  9# change to a rule's controls, checks, or thresholds so reports stay traceable.
 10name: AWS ITGC ruleset
 11version: "2026.08.0"
 12platform: aws
 13
 14rules:
 15  - id: aws.iam.console-mfa
 16    title: Console users have MFA enabled
 17    table: iam_users
 18    severity: high
 19    controls: [SOC2:CC6.1, ISO:A.5.17, NIST:IA-2]
 20    rationale: >
 21      A user who can sign in to the console without a second factor is a single
 22      stolen password away from account access. MFA is the baseline control for
 23      interactive human access.
 24    remediation: Enforce MFA for all IAM users with console access, or remove their console password.
 25    check:
 26      type: fail_rows_where
 27      when:
 28        all:
 29          - {column: console_password, op: is_true}
 30          - {column: mfa_enabled, op: is_false}
 31
 32  - id: aws.iam.key-rotation
 33    title: Access keys are rotated within 90 days
 34    table: iam_users
 35    severity: medium
 36    controls: [ISO:A.5.17, NIST:IA-5]
 37    rationale: >
 38      Long-lived access keys widen the window in which a leaked credential is
 39      useful. Rotating keys bounds that exposure.
 40    remediation: Rotate or delete access keys older than 90 days.
 41    check:
 42      type: fail_rows_where
 43      when: {column: oldest_key_age_days, op: gt, value: 90}
 44
 45  - id: aws.root.mfa
 46    title: Root account has MFA enabled
 47    table: account_security
 48    severity: high
 49    controls: [SOC2:CC6.1, ISO:A.8.2, NIST:IA-2]
 50    rationale: >
 51      The root account can perform every action in the account and cannot be
 52      restricted by IAM policy. MFA on root is a foundational control.
 53    remediation: Enable a hardware or virtual MFA device on the root user.
 54    check:
 55      type: assert_row
 56      require:
 57        - {column: root_mfa_enabled, op: is_true}
 58
 59  - id: aws.root.no-access-keys
 60    title: Root account has no access keys
 61    table: account_security
 62    severity: high
 63    controls: [SOC2:CC6.1, ISO:A.8.2, NIST:AC-6]
 64    rationale: >
 65      Programmatic root access keys are unnecessary and dangerous — anything
 66      root can do should be done through named, least-privilege identities.
 67    remediation: Delete all access keys on the root user.
 68    check:
 69      type: assert_row
 70      require:
 71        - {column: root_access_keys_present, op: is_false}
 72
 73  - id: aws.iam.password-policy
 74    title: Account password policy meets baseline strength
 75    table: password_policy
 76    severity: medium
 77    controls: [ISO:A.5.17, NIST:IA-5]
 78    rationale: >
 79      A weak password policy undermines every password-based control. The
 80      baseline here — length, complexity, and rotation — reflects common
 81      hardening guidance.
 82    remediation: Set a minimum length of 14, require symbols and numbers, and cap password age at 90 days.
 83    check:
 84      type: assert_row
 85      require:
 86        - {column: minimum_length, op: gte, value: 14}
 87        - {column: require_symbols, op: is_true}
 88        - {column: require_numbers, op: is_true}
 89        - {column: max_age_days, op: lte, value: 90}
 90
 91  - id: aws.network.no-open-ssh
 92    title: No security group exposes SSH to the internet
 93    table: open_security_groups
 94    severity: high
 95    controls: [SOC2:CC6.6, ISO:A.8.20, NIST:SC-7]
 96    rationale: >
 97      SSH (port 22) reachable from 0.0.0.0/0 invites credential-stuffing and
 98      exploitation of the host directly from the public internet.
 99    remediation: Restrict inbound SSH to known CIDR ranges or a bastion, or use SSM Session Manager.
100    check:
101      type: fail_rows_where
102      when:
103        all:
104          - {column: open_to, op: equals, value: 0.0.0.0/0}
105          - {column: from_port, op: lte, value: 22}
106          - {column: to_port, op: gte, value: 22}
107
108  - id: aws.s3.no-public-access
109    title: No S3 bucket allows public access
110    table: s3_public_access
111    severity: high
112    controls: [SOC2:CC6.6, ISO:A.8.20, NIST:SC-7]
113    rationale: >
114      Publicly readable or writable buckets are a leading cause of data
115      exposure. audit-tools lists only buckets that permit public access, so any
116      row here is a finding.
117    remediation: Enable Block Public Access at the account and bucket level; remove public bucket policies and ACLs.
118    check:
119      type: fail_if_any_rows
120
121  - id: aws.cloudtrail.logging
122    title: A multi-region CloudTrail is actively logging
123    table: cloudtrail
124    severity: high
125    controls: [SOC2:CC7.2, ISO:A.8.15, NIST:AU-2]
126    rationale: >
127      Without an active trail there is no reliable record of account activity —
128      the evidence auditors and responders rely on simply does not exist.
129    remediation: Enable a multi-region CloudTrail with log file validation and confirm it is logging.
130    check:
131      type: require_any_row
132      when:
133        all:
134          - {column: is_logging, op: is_true}
135          - {column: multi_region, op: is_true}