🐍 Python · AWS · IAM

aws_04_inactive_iam_users.py

AWS-04 — AWS-04: Inactive IAM Users
boto3 only Read-only IAM CIS AWS 1.15 Exit codes for pipeline use

Stale IAM accounts are a persistent problem in every organisation that has been running AWS for more than two years. An employee leaves. IT removes their AD account but nobody touches IAM. A contractor finishes. Their access key stays active in a script nobody runs any more. Six months later that account still has the same permissions it had when it was actively used — and nobody is watching it. Stale accounts are a favoured target for attackers because they are unlikely to trigger alerts when accessed.

An ISO 27001 surveillance audit requires evidence of a quarterly access review for cloud environments. You run this script across four accounts. One account returns three inactive users: an ex-employee whose console access was never revoked, a service account with access keys that have not been used in 412 days, and a contractor account created for a project that completed eight months ago. The script output becomes the access review evidence — username, last activity date, days inactive, and recommended disposition.

aws_04_inactive_iam_users.py enumerates all IAM users, checks each for a console login profile, and evaluates the most recent activity across console logins and access keys. Users whose last activity was more than 90 days ago (configurable via --days) and users who have never been used are listed as inactive findings. Users with no login mechanism at all are excluded. The script sorts results by days inactive, longest first.

Regulation coverage: NIST CSF PR.AC-1 | SOX ITGC AC-04 | PCI DSS 8.8 | ISO 27001 A.9.2.6 | FFIEC CAT | DORA Art.9

Prerequisites: pip install boto3 · iam:ListUsers · iam:GetLoginProfile · iam:ListAccessKeys · iam:GetAccessKeyLastUsed · sts:GetCallerIdentity

Script

Terminal
# Install dependency
$ pip install boto3

# Run with default credentials
$ python3 aws_04_inactive_iam_users.py

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

# Custom inactivity threshold (e.g. 60 days for PCI)
$ python3 aws_04_inactive_iam_users.py --days 60

# Save JSON evidence
$ python3 aws_04_inactive_iam_users.py --profile my-audit-role --save
IAM Permission Why it is needed
iam:ListUsersEnumerates all IAM users in the account
iam:GetLoginProfileDetermines whether each user has a console password enabled
iam:ListAccessKeysLists access keys for each user
iam:GetAccessKeyLastUsedReturns the last used date for each access key
sts:GetCallerIdentityResolves account ID for the evidence record
Sample output — PASS
  Scope        8 total IAM users evaluated

  ✓  RESULT: PASS

  Finding
  All 8 IAM users with active login mechanisms have been active
  within the last 90 days. No inactive accounts found.

  Raw: {"total_users": 8, "inactive_count": 0}
Sample output — FAIL
  Scope        8 total IAM users evaluated

  ✗  RESULT: FAIL
  Risk Rating    HIGH

  Inactive user detail
  ──────────────────────────────────────────────────────────────
  Username                Last activity           Days    Status
  ──────────────────────────────────────────────────────────────
  svc-reporting           2025-07-10T08:22:00Z    236     INACTIVE
  john.doe                2025-09-01T14:05:00Z    183     INACTIVE
  deploy-legacy           NEVER                   412     NEVER_USED

  Finding
  3 IAM users inactive for more than 90 days or never used.
  Stale accounts retain original permissions and are valid
  attack targets.

  Remediation
  Disable or delete all 3 inactive users. Confirm no service
  dependency before deleting. Document disposition.

Regulation map

Framework Control / Clause Obligation
NIST CSF 2.0PR.AC-1Credentials for departed users and inactive accounts must be revoked in a timely manner.
SOX ITGCAC-04Periodic user access reviews must identify and remove stale accounts with access to financial systems.
PCI DSS v4.08.8Accounts of terminated users must be removed or disabled within a defined timeframe. Inactive accounts must be reviewed quarterly.
ISO 27001:2022A.9.2.6Formal access removal procedures must ensure accounts are disabled when employment or contract ends.
FFIEC CATBaseline — IAMTimely revocation of user access for separated employees and contractors is a baseline requirement.
DORA (EU)Article 9ICT access rights must be reviewed at regular intervals and revoked when no longer required.

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

Request an addition