# AWS Config compliance result proving long-lived IAM access keys (including those used by service/non-user identities) are rotated within the maximum age

> FedRAMP Consolidated Rules for 2026 v2026.07.14.01 · updated 2026-07-14
> Canonical page: /collect/config-access-keys-rotated

Recipe id: `config-access-keys-rotated` · cadence continuous · 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-SNU`
- KSI `KSI-IAM-APM`
- control `ia-5`

## Collection

Kind: `config-rule`

```sh
# access-keys-rotated
aws configservice get-compliance-details-by-config-rule --config-rule-name access-keys-rotated --compliance-types NON_COMPLIANT
# configuration-recorder-status
aws configservice describe-configuration-recorder-status
# access-keys-rotated-evaluation-status
aws configservice describe-config-rule-evaluation-status --config-rule-names access-keys-rotated
```

## Expected output

EvaluationResults array; empty NON_COMPLIANT set means every active access key is within maxAccessKeyAge. Managed rule identifier: ACCESS_KEYS_ROTATED (maxAccessKeyAge parameter, e.g. 90) Plus describe-configuration-recorder-status showing recording=true and, per rule, describe-config-rule-evaluation-status showing FirstEvaluationStarted=true with a LastSuccessfulEvaluationTime — the proof the empty set was produced by a check that ran.

## Assertions

- {"field":"access-keys-rotated.EvaluationResults","op":"count_eq","value":0,"controls":["ia-5"],"description":"No active access key is older than the rule's maxAccessKeyAge."}
- {"field":"configuration-recorder-status.ConfigurationRecordersStatus[].recording","op":"eq","value":true,"controls":["ia-5"],"description":"The configuration recorder is on — without it an empty NON_COMPLIANT set is indistinguishable from a recorder that never ran."}
- {"field":"access-keys-rotated-evaluation-status.ConfigRulesEvaluationStatus[].FirstEvaluationStarted","op":"eq","value":true,"controls":["ia-5"],"description":"access-keys-rotated has evaluated at least once; a deployed-but-never-evaluated rule also returns an empty result."}
- {"field":"access-keys-rotated-evaluation-status.ConfigRulesEvaluationStatus[].LastSuccessfulEvaluationTime","op":"exists","controls":["ia-5"],"description":"access-keys-rotated has a successful evaluation on record."}

## GovCloud

AWS Config and this managed rule are available in AWS GovCloud (US); resource ARNs use partition arn:aws-us-gov

## Notes

Strongest evidence for non-user auth is the absence of long-lived keys entirely (prefer IAM roles / temporary credentials). Where keys must exist, this rule proves rotation. Set maxAccessKeyAge to your policy (<=90d). The rule's verdict is only as strong as the maxAccessKeyAge an operator set, and the output does not carry the parameter — a human confirms it matches the SSP's rotation period. Root-user access keys are outside the rule by AWS's documented limitation. Filed under IA-05 base: key age tests IA-05 (g), not AC-02 (01).

## References

- {"title":"AWS Config managed rule: access-keys-rotated (ACCESS_KEYS_ROTATED, maxAccessKeyAge default 90 days; does not apply to root user access keys)","url":"https://docs.aws.amazon.com/config/latest/developerguide/access-keys-rotated.html"}
