🐍 Python · AWS · IAM

aws_02_root_access_keys.py

AWS-02 — AWS-02: Root Account Access Keys
boto3 only Read-only IAM CIS AWS 1.12 Exit codes for pipeline use

Root access keys are programmatic credentials that carry the full power of the root account. No IAM policy can constrain them. AWS explicitly states they should never exist. Yet they appear in legacy accounts, old automation pipelines, and environments where an early engineer took a shortcut years ago. An inactive root key sitting in an old Ansible playbook or a leaked .env file is enough to hand an attacker complete control of the account.

A client is migrating to a new DevOps platform and has asked you to review their AWS security posture before cutover. You run this script. It returns FAIL: two root access keys detected, one of which has never been used. Neither the current team nor the outgoing team can explain where they came from. This becomes the first finding in the report. Delete before migration proceeds, document disposition, confirm no pipeline dependency.

aws_02_root_access_keys.py calls iam:GetAccountSummary and reads AccountAccessKeysPresent. A value of 0 is a PASS. Any non-zero value is CRITICAL. The script reports the exact key count, whether active or inactive. Both states are a finding: inactive keys can be re-activated.

Regulation coverage: NIST CSF PR.AC-4 | SOX ITGC AC-02 | PCI DSS 8.2.1 | ISO 27001 A.9.2.3 | FFIEC CAT | DORA Art.9

Prerequisites: pip install boto3 · iam:GetAccountSummary · sts:GetCallerIdentity

Script

Terminal
# Install dependency
$ pip install boto3

# Run with default credentials
$ python3 aws_02_root_access_keys.py

# Named profile
$ python3 aws_02_root_access_keys.py --profile my-audit-role

# Save JSON evidence
$ python3 aws_02_root_access_keys.py --profile my-audit-role --save

# JSON only — for pipeline use
$ python3 aws_02_root_access_keys.py --json-only | jq .result
IAM Permission Why it is needed
iam:GetAccountSummaryReads AccountAccessKeysPresent — counts root-level access keys only
sts:GetCallerIdentityResolves account ID for the evidence record. Fails gracefully if absent.
Sample output — PASS
  Check        AWS-02 — Root Account Access Keys
  CIS Ref      CIS AWS Foundations Benchmark v2.0 — Controls 1.4 / 1.12
  Account      123456789012

  ✓  RESULT: PASS

  Finding
  No access keys exist on the root account. Correct configuration.

  Raw: {"AccountAccessKeysPresent": 0}
Sample output — FAIL
  Check        AWS-02 — Root Account Access Keys
  CIS Ref      CIS AWS Foundations Benchmark v2.0 — Controls 1.4 / 1.12
  Account      123456789012

  ✗  RESULT: FAIL
  Risk Rating    CRITICAL

  Finding
  2 root account access keys detected (active or inactive). Root
  access keys bypass all IAM policies, SCPs, and permission
  boundaries. AWS states root access keys should never exist.
  Delete immediately.

  Remediation
  Sign in as root → Account menu → Security credentials → Access
  keys → Delete all keys. Do not deactivate. Delete.

  Raw: {"AccountAccessKeysPresent": 2}

Regulation map

Framework Control / Clause Obligation
NIST CSF 2.0PR.AC-4Access permissions must be managed consistent with the principle of least privilege. Root keys violate this principle by design.
SOX ITGCAC-02Privileged credentials must be inventoried and controlled. Undocumented root keys are a direct control failure.
PCI DSS v4.08.2.1All accounts must be assigned to an individual. Root access keys with no owner attribution fail this requirement.
ISO 27001:2022A.9.2.3Use of privileged access rights must be controlled and restricted. Root-level programmatic credentials breach this control.
FFIEC CATBaseline — IAMExcessive privileges must be removed. Root access keys with no business justification are an automatic escalation.
DORA (EU)Article 9Privileged access controls must prevent unauthorised use of ICT systems. Root keys with no access restrictions fail this requirement.

Feedback welcome: Corrections, ideas, and requests — grcguy@rtapulse.com.

Request an addition