Skip to content

Keyboard shortcuts

Go

  • Scope — the control cataloggm
  • Plan — your last certification classgp
  • Collect — the recipe indexgc
  • The control you are workinggw
  • Startgh

Move

  • Next rowj
  • Previous rowk
  • Previous in this run[
  • Next in this run]
  • Filter this page's list/
  • Search everythingK

Act

  • Copy this page's permalinky
  • Toggle dark moded
  • This sheet?

Rows are whatever the current page lists — controls on Scope, recipes on Plan and Collect.

Control index

The state of every credential in the account as of a stated moment, the enabled-or-disabled status of every workforce identity in the identity store, and the CloudTrail record of the revocations themselves — the five API calls that actually revoke standing access, each with the time it happened and the administrator who did it

The API supplies the facts, but a human judgement against a documented baseline turns them into evidence.

partial — needs judgementclicontinuousAWS IAMAWS IAM Identity CenterAWS CloudTrail

Fetch

$ aws iam generate-credential-report
$ aws iam get-credential-report
$ aws identitystore list-users --identity-store-id <IDENTITY_STORE_ID>
$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=DeleteUser --start-time <T0> --end-time <T1>
$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=DeleteLoginProfile --start-time <T0> --end-time <T1>
$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=DeleteAccessKey --start-time <T0> --end-time <T1>
$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=UpdateAccessKey --start-time <T0> --end-time <T1>
$ aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=DeactivateMFADevice --start-time <T0> --end-time <T1>

Expected output

From generate-credential-report, a State of STARTED, INPROGRESS or COMPLETE — AWS stores ONE report per account and regenerates it at most once every four hours, so a request made inside that window silently returns the existing report rather than a fresh one. From get-credential-report, Content (the report, base64-encoded CSV), ReportFormat, and GeneratedTime — the timestamp that says what moment the evidence describes, and the field the freshness assertion reads. The CSV columns are: user, arn, user_creation_time, password_enabled, password_last_used, password_last_changed, password_next_rotation, mfa_active, access_key_1_active, access_key_1_last_rotated, access_key_1_last_used_date, access_key_1_last_used_region, access_key_1_last_used_service, the same five for access_key_2, cert_1_active, cert_1_last_rotated, cert_2_active, cert_2_last_rotated, and additional_credentials_info. Note what the report does NOT cover, because it bounds the whole recipe: AWS documents it as including only passwords, THE FIRST TWO access keys per user, MFA devices and X.509 signing certificates — service-specific credentials such as CodeCommit passwords are absent, as is any access key beyond the second, and additional_credentials_info is the only hint that more exist. From identitystore list-users, Users[] with UserId, UserName, ExternalIds and UserStatus, which is ENABLED or DISABLED. There are five lookup calls rather than one because lookup-events accepts exactly ONE lookup attribute per request, and revocation is five different API calls: deleting the user, deleting the console login profile, deleting an access key, setting an access key Inactive, and deactivating the MFA device. From each lookup-events call, Events[] with EventName, EventTime, Username — the REQUESTER who performed the revocation, not the identity revoked — and the CloudTrailEvent JSON, where requestParameters names the user or device that was acted on.

Assertions — what makes it a pass

Assertions for The state of every credential in the account as of a stated moment, the enabled-or-disabled status of every workforce identity in the identity store, and the CloudTrail record of the revocations themselves — the five API calls that actually revoke standing access, each with the time it happened and the administrator who did it: the field checked, the condition it must satisfy, the rows it applies to, and the controls a pass proves.
FieldMust beForProves
get-credential-report.GeneratedTimemax_age_days 1The credential report being read describes a moment within the last day. AWS regenerates at most once every four hours and returns the stored report inside that window, so calling generate before get does NOT make the result fresh — GeneratedTime is the only field that says how old the evidence is. Substitute the interval your SSP commits to for revocation review.every rowPS-04

Authored opinion, like the commands. Units live in the operator name — max-age-days is days, and nothing here is converted for you.

Map — what it proves

  • recipe1
Key Security Indicators
NIST 800-53 controls
  • recipean authored recipe collects evidence for this control
  • KSI onlya Key Security Indicator reaches it, but no recipe is authored yet
  • orphanno Key Security Indicator reaches it — a person writes it up instead

What else these families can fetch:PS 2/11

GovCloud

IAM, the credential report and CloudTrail all operate in both AWS GovCloud (US) Regions and every call here is available; ARNs use partition arn:aws-us-gov. IAM Identity Center is available in both Regions but has NO multi-Region support, so list-users must be run against the Region its instance was enabled in. The CloudTrail calls carry the one real trap: IAM is a global service and its events are recorded in AWS GovCloud (US-West), us-gov-west-1, while Event history and lookup-events show these events in the Region where they occurred — so a DeleteUser lookup issued against us-gov-east-1 returns an empty Events[] and exits zero, which reads exactly like a period in which nobody was separated. The same shape applies in the commercial partition, where those events land in us-east-1.

Notes & assertions

PS-04 is a list of things that happen when someone leaves: disable system access within a defined period, revoke the authenticators, conduct an exit interview, retrieve organizational property, retain access to the information the person worked on, and notify named personnel within a period. AWS holds evidence for the first two and nothing whatever for the other four. And it holds those two only as state and history, never as subject. The credential report says every credential in the account and what shape it is in; CloudTrail says which revocation happened, when, and by which administrator. Five lookups rather than two, because lookup-events takes one lookup attribute per call and revocation is not one API: an estate that follows this recipe's own advice and DISABLES rather than deletes never emits DeleteUser at all, so a collection that watched only for deletions would return an empty Events[] on a correctly executed separation. UpdateAccessKey is in the list for the same reason — setting a key Inactive is a revocation that deletes nothing. What no call knows is that a PERSON was terminated. There is no roster in AWS, no employment status, no separation date — so the join between 'this human left on the 4th' and 'this identity was revoked on the 6th' is made by a human against an HR record, and the period the control defines is checked on that join and not here. This recipe produces the AWS-side column. It is partial for that reason and no assertion below pretends otherwise. That is also why there is exactly one assertion. Any clause of the form 'no user has an active credential' is false on every working account and would be answering about the whole population when the control is about a named few; a clause over 'users your tagging marks as separated' would invent a third tagging convention to answer a question the HR record already answers better. So the single assertion is about the EVIDENCE rather than the estate: that the report describes a recent moment. A credential report is a snapshot with a timestamp, and a stale one is a true statement about a past that has already been superseded. Read the four-hour rule as a collection constraint, not a detail. AWS stores one credential report per account and regenerates it at most once every four hours; a generate call inside that window returns the report you already had. So generate-then-get does not guarantee freshness, GeneratedTime is what does, and a collector that runs the two calls back to back and assumes the second reflects the first is reporting on a state up to four hours old. The report's coverage is narrower than its name suggests, and the gap is exactly where a separation goes wrong. AWS documents it as covering passwords, the first two access keys per user, MFA devices and X.509 signing certificates. A third access key is not in it. Service-specific credentials are not in it. A separated user whose remaining access is a CodeCommit password or a long-term service credential appears in this report as fully revoked. additional_credentials_info is the only signal that anything else exists, and closing that gap needs ListAccessKeys and ListServiceSpecificCredentials per user, which this recipe does not collect and an assessment should. On a well-run estate the IAM half is the small half. Workforce identities live in the identity store and a separation there is UserStatus DISABLED rather than a deletion, which is why the third call is collected: an account whose credential report lists no IAM user for a departed employee, while the identity store still lists them as ENABLED, has not revoked anything — and the credential report, which sees only IAM, cannot show it. Disabling rather than deleting is also the better practice for this control, because it preserves the identifier — see the IA-04 recipe on why a freed name is a hazard. One KSI was deliberately not claimed. KSI-IAM-SUS asks that privileged accounts be disabled or secured IN RESPONSE TO SUSPICIOUS ACTIVITY, and a routine separation is not suspicious activity; the output is identical in both cases and cannot tell an assessor which one it is looking at. KSI-IAM-JIT was dropped for a quieter reason. Its statement asks for a least-privileged, role and attribute-based, and JUST-IN-TIME authorization model, persistently reviewed. Nothing in five commands over STANDING credentials evaluates a just-in-time or attribute-based model; only the 'persistently reviewed' tail is touched, and that tail is already what KSI-IAM-ELP carries here. KSI-IAM-ELP is earned outright: an identity that outlives its holder is precisely a failure of the rule that each user can access only what they need.

References

This AWS mapping is authored opinion (overlay v3.0.0), versioned separately from the dataset and written against ruleset 2026.07.14.01. The upstream FedRAMP dataset names none of these tools.

The Identity and Access Management run (16)

  • automatable
  • partial — needs judgement
  • narrative — no API proves this

Every authored recipe filed under IAM, in the order the plan works them. The mark says how much of the evidence the command produces on its own.