Skip to main content
emnode
Compliance Medium severity

AWS Security Hub · IAM

IAM.22: IAM credentials unused for 45 days should be removed

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub IAM.22 check?

IAM.22 fails when an IAM user has a password or active access key that has been unused for 45 days or more. It and IAM.8 share the same AWS Config managed rule, iam-user-unused-credentials-check; IAM.22 evaluates it at the CIS-aligned maxCredentialUsageAge of 45 days, where IAM.8 uses 90.

Why does IAM.22 matter?

Disabling or removing unused credentials reduces the window of opportunity for a credential tied to a compromised or abandoned account to be misused. The 45-day threshold is the CIS AWS Foundations Benchmark recommendation and closes that window sooner than the 90-day IAM.8 check, leaving less time for an exposed but idle password or access key to be useful to an attacker.

How do I fix IAM.22?

  1. Pull the credential report and identify passwords and access keys idle for 45+ days.
  2. Deactivate each stale key and watch CloudTrail for a short observation window to confirm nothing depends on it.
  3. Delete the deactivated keys and remove unused console passwords.
  4. Set the AWS Config rule's maxCredentialUsageAge to 45 so the finding stays closed.

Remediation script · bash

# Find active credentials idle past 45 days and disable them (review before deleting).
CUTOFF=$(date -u -d '45 days ago' +%Y-%m-%d)
aws iam generate-credential-report >/dev/null
aws iam get-credential-report --query Content --output text | base64 -d \
  | awk -F, -v c="$CUTOFF" 'NR>1 && $9=="true" && $11<c {print $1, $10}'
aws iam update-access-key --user-name old-contractor \
  --access-key-id AKIAIOSFODNN7EXAMPLE --status Inactive

# Apply the CIS-aligned IAM password policy in one idempotent call.
aws iam update-account-password-policy --minimum-password-length 14 \
  --require-uppercase-characters --require-lowercase-characters \
  --require-numbers --require-symbols --password-reuse-prevention 24

# A clear-text key in a build project is compromised: rotate and delete, never just relocate.
aws iam delete-access-key --user-name ci-deploy --access-key-id AKIAIOSFODNN7EXAMPLE

Full walkthrough (console steps, edge cases and verification) in the lesson Rotate and remove stale IAM credentials.

Is IAM.22 a false positive?

The underlying rule reads from the IAM credential report, which only refreshes every four hours, so a credential that's actually in regular use can show a stale "last used" timestamp and trip the control right after a long idle gap; wait for the report to catch up before deactivating anything that a workload still depends on. A break-glass or disaster-recovery credential is meant to sit unused for long stretches by design, and it will reliably cross the 45-day threshold even though deleting it would be exactly the wrong move; for those, document a Security Hub exception rather than rotating away the emergency access. Because IAM is global, recording global resources in a single Region also means you should disable this periodic control in the other Regions to avoid duplicate findings, not chase the same idle credential several times.

Part of the learning path Lock down access
  • IAM.1 A policy grants full "*" administrative privileges
  • IAM.2 Policies attached directly to users do not scale or audit cleanly
  • IAM.3 Long-lived access keys have not been rotated
  • IAM.4 The root user still has long-lived access keys
  • IAM.5 Console users without MFA are one phish from compromise
  • IAM.6 The root user is not protected by hardware MFA
  • IAM.7 The IAM password policy is too weak
  • IAM.8 Unused IAM keys and passwords are waiting to be leaked
  • IAM.9 The root user can sign in without MFA
  • IAM.10 IAM user password policies should be strong (PCI DSS)
  • IAM.19 MFA should be enabled for all IAM users
  • IAM.21 Wildcard permissions grant far more access than intended