# Account-wide credential report proving MFA is active per principal and that passwords/access keys are rotated within policy

> FedRAMP Consolidated Rules for 2026 v2026.07.14.01 · updated 2026-07-14
> Canonical page: /collect/iam-credential-report

Recipe id: `iam-credential-report` · cadence monthly · partial

> **Authored opinion.** AWS overlay v3.0.0, written
> against dataset 2026.07.14.01. The upstream
> FedRAMP rules name none of these tools; this mapping is ours.

## What it proves

- KSI `KSI-IAM-APM`
- KSI `KSI-IAM-ELP`
- control `ia-2`
- control `ia-5`

## Collection

Kind: `cli`

```sh
# generate-credential-report
aws iam generate-credential-report
# credential-report-generated-time
aws iam get-credential-report --query GeneratedTime --output text
# credential-report
aws iam get-credential-report --query Content --output text | base64 --decode
```

## Expected output

CSV, one row per IAM principal with columns including password_enabled, mfa_active, password_last_changed, access_key_1_active, access_key_1_last_rotated, access_key_2_last_rotated

## Assertions

- {"field":"credential-report-generated-time","op":"max_age_days","value":1,"controls":["ia-2","ia-5"],"description":"The report being read was generated within the last day — a stored report is served for up to four hours, and nothing else bounds its age."}
- {"field":"credential-report[].mfa_active","op":"eq","value":"TRUE","where":[{"field":"password_enabled","op":"eq","value":"TRUE"}],"controls":["ia-2"],"description":"Every principal with a console password has MFA active."}
- {"field":"credential-report[].access_key_1_last_rotated","op":"max_age_days","value":90,"where":[{"field":"access_key_1_active","op":"eq","value":"TRUE"}],"controls":["ia-5"],"description":"Every active first access key was rotated within the last 90 days."}
- {"field":"credential-report[].access_key_2_last_rotated","op":"max_age_days","value":90,"where":[{"field":"access_key_2_active","op":"eq","value":"TRUE"}],"controls":["ia-5"],"description":"Every active second access key was rotated within the last 90 days."}

## GovCloud

identical API and CSV schema; principal ARNs use partition arn:aws-us-gov

## Notes

Assert mfa_active=true for every password_enabled=true principal, and (now - access_key_N_last_rotated) <= 90d for every active key. generate-credential-report is async; poll get-credential-report until State=COMPLETE (report is regenerated at most every 4 hours). mfa_active is TRUE for a virtual TOTP device as well as a FIDO key, and the CSV covers IAM users and the root user only — a human confirms from the identity provider's own report that console authentication is phishing-resistant (the IA-02 (01)/(02) guidance) and that federated Identity Center or external-IdP sign-ins are covered elsewhere. The 90-day threshold is CIS Benchmark 1.14's, not FedRAMP's. Filed under IA-02 and IA-05 base: key age tests IA-05 (g), not AC-02 (01)'s automated account management or IA-05 (01)'s password rules.

## References

- {"title":"Generate credential reports for your AWS account (CSV columns; a report can be generated at most once every four hours)","url":"https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_getting-report.html"}
- {"title":"AWS CLI: iam generate-credential-report","url":"https://docs.aws.amazon.com/cli/latest/reference/iam/generate-credential-report.html"}
- {"title":"AWS CLI: iam get-credential-report","url":"https://docs.aws.amazon.com/cli/latest/reference/iam/get-credential-report.html"}
