Skip to content

IAM requests, responses and pagination

[!caution]

This service is not deployed. There is no iam.shelfcs.com or sts.shelfcs.com in the published endpoint list, and no call on this page will answer. This page is the specification, not a description of something running.

For the identity system that does exist — the identity service users, one project, one role, and EC2 access keys — read Identity, as deployed.

IAM speaks the standard AWS query protocol. It is not the same protocol EC2 speaks, and the differences are not cosmetic: different response envelope, different request-id element, different pagination parameters.

Read this page before implementing an IAM client or the IAM service.

  • An access key id and secret access key

Form-encoded POST, with the action and version as parameters:

POST / HTTP/1.1
Host: iam.shelfcloud.com
Content-Type: application/x-www-form-urlencoded; charset=utf-8
X-Amz-Date: 20260903T142207Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIA.../20260903/hel1/iam/aws4_request, ...
Action=ListUsers&Version=2010-05-08&MaxItems=100
<ListUsersResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
<ListUsersResult>
<IsTruncated>true</IsTruncated>
<Users>
<member>
<UserName>deploy</UserName>
<UserId>AIDA0A1B2C3D4E5F60718</UserId>
<Arn>arn:aws-shelf:iam::123456789012:user/deploy</Arn>
<Path>/</Path>
<CreateDate>2026-09-03T14:22:07Z</CreateDate>
</member>
</Users>
<Marker>eyJwYWdlIjoyfQ</Marker>
</ListUsersResult>
<ResponseMetadata>
<RequestId>b1e2c3d4-5678-90ab-cdef-1234567890ab</RequestId>
</ResponseMetadata>
</ListUsersResponse>

Three things a client depends on and an implementer must get exactly right:

  • The result is wrapped in <ActionResult> inside <ActionResponse>.
  • List members are <member> elements, not elements named after the type.
  • The request id lives in <ResponseMetadata><RequestId> — RequestId, with a lowercase d, unlike EC2’s <RequestID>.
<ErrorResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/">
<Error>
<Type>Sender</Type>
<Code>NoSuchEntity</Code>
<Message>The user with name deploy cannot be found.</Message>
</Error>
<RequestId>b1e2c3d4-5678-90ab-cdef-1234567890ab</RequestId>
</ErrorResponse>

<Type> is Sender for client errors and Receiver for server errors. EC2’s envelope has no <Type>; IAM’s does. A client written for one cannot parse the other.

IAM does not use MaxResults and NextToken. It uses:

ParameterDirectionMeaning
MaxItemsRequestItems per page. Default 100, maximum 1000
MarkerRequestThe marker from the previous response
IsTruncatedResponsetrue when more items remain
MarkerResponsePresent when IsTruncated is true
PathPrefixRequestRestrict to a path prefix

This is not a choice. Every AWS SDK’s IAM paginators key on Marker/IsTruncated. An implementation that returned NextToken here would have its token discarded by the client, which would then report only the first page — a silently truncated list of users, in the service that decides who can do what.

marker = None
while True:
kwargs = {"MaxItems": 1000}
if marker:
kwargs["Marker"] = marker
page = iam.list_users(**kwargs)
handle(page["Users"])
if not page.get("IsTruncated"):
break
marker = page["Marker"]

The EC2 pagination rules do not apply to IAM. They are documented separately and each page says which service it governs.

The signing name is iam.

PROPOSED: the signing region is hel1, and us-east-1 is also accepted.

Both are accepted because IAM is a global service in AWS with us-east-1 hardcoded in the SDK endpoint rulesets. When an endpoint is overridden, some SDK versions still sign with us-east-1 and others sign with the caller’s configured region. Accepting only one produces signature failures that vary by SDK and by version, which is worse than either answer alone.

IAM is eventually consistent. A credential or policy change may take a short time to be visible to every service.

PROPOSED: we publish the propagation bound, because a customer revoking a compromised key needs to know when the revocation is actually in force.