Infra, Illustrated.
AWS · IDENTITY & CREDENTIALS

AWS Identity Pipeline

How AWS judges a request, and how callers get credentials to send it.

MAYA → PRODUCTION REPORTSFLOW EXPLORER · INTERMEDIATEPublished Sep 6, 2026 · Reviewed Oct 15, 2026
ACTIVE VIEWOne request
Maya · list reports · workforce 111… → production 222…
identity / trust request / response configuration relationship (dashed) blocked exchange
01 / FOUR QUESTIONS

Every AWS request answers four questions

Maya lists the reports bucket from her laptop. Follow the one request and see what AWS reads from it before S3 does anything.

STEP 1 OF 5 · The request arrives

Maya's CLI sends one signed HTTPS request to the reports bucket. Before S3 lists anything, AWS has to decide whether this request may run.

One signed request, broken into the four questions AWS asksShown: Maya's CLI, signed request. Maya's CLI to signed request: signs.

What travels over the wire

GET /?list-type=2 HTTP/1.1Host: amzn-s3-demo-bucket-reports.s3.amazonaws.comAuthorization: AWS4-HMAC-SHA256 Credential=ASIA…DEMO/20261015/ap-south-1/s3/aws4_request, …X-Amz-Security-Token: [session token]X-Amz-Date: 20261015T104200Z
STEP 2 OF 5 · WHO is asking

The access key ID in the signature belongs to a temporary credential set, and that set belongs to a role session. The session is who is asking, not Maya's laptop or her name.

One signed request, broken into the four questions AWS asksShown: Maya's CLI, signed request, WHO. signed request to WHO.

What AWS knows so far

Principal
arn:aws:sts::222222222222:assumed-role/SupportRead/mayanew
STEP 3 OF 5 · WHAT it wants

S3 turns the API call into an action and a resource. ListObjectsV2 is checked as s3:ListBucket, and it acts on the bucket itself, not on the objects inside it.

One signed request, broken into the four questions AWS asksShown: Maya's CLI, signed request, WHO, WHAT. signed request to WHAT.

What AWS knows so far

Principal
arn:aws:sts::222222222222:assumed-role/SupportRead/maya
Action
s3:ListBucketnew
Resource
arn:aws:s3:::amzn-s3-demo-bucket-reportsnew
STEP 4 OF 5 · FROM WHERE

The connection adds facts about where and how the request came: the source IP, whether it came through a VPC endpoint, whether it used TLS, and the time. Policies read these as condition keys.

One signed request, broken into the four questions AWS asksShown: Maya's CLI, signed request, WHO, WHAT, FROM WHERE. signed request to FROM WHERE.

What AWS knows so far

Principal
arn:aws:sts::222222222222:assumed-role/SupportRead/maya
Action
s3:ListBucket
Resource
arn:aws:s3:::amzn-s3-demo-bucket-reports
aws:SourceIp
203.0.113.24new
aws:SecureTransport
truenew
aws:CurrentTime
2026-10-15T10:42:00Znew
STEP 5 OF 5 · HOW it is judged

AWS gathers every policy that applies: the role's identity policy, the bucket policy, the organization's SCPs and the role's permissions boundary. It compares the request with each one. AWS calls the four parts of a request PARC: Principal, Action, Resource and Condition.

One signed request, broken into the four questions AWS asksShown: Maya's CLI, signed request, WHO, WHAT, FROM WHERE, decision, HOW. WHO to decision. WHAT to decision. FROM WHERE to decision. HOW to decision.

The request context

Principal
arn:aws:sts::222222222222:assumed-role/SupportRead/maya
Action
s3:ListBucket
Resource
arn:aws:s3:::amzn-s3-demo-bucket-reports
aws:SourceIp
203.0.113.24
aws:SecureTransport
true
aws:CurrentTime
2026-10-15T10:42:00Z
INSPECTOR

A request becomes a request context

AWS turns each signed request into a request context: who sent it, the action, the resource, and facts about the request such as the source IP and time. Every policy is matched against that context. The signature only proves the request came from the credential holder; whether the action is allowed is decided by the policies.

WHO
Principal: the session or user that signed
WHAT
Action + Resource ARN
FROM WHERE
Condition keys from the request
HOW
Effect and type of each policy that applies
SEE YOUR OWN PRINCIPALaws sts get-caller-identity
WORTH KNOWING

An API name and its IAM action can differ: ListObjectsV2 is authorized as s3:ListBucket. The Service Authorization Reference lists the action and resource type for every API.

IAM: the request context ↗S3: policy actions ↗IAM: Signature Version 4 ↗

THE POINT TO KEEPBefore reading a policy, write the request as principal, action, resource and context; every policy is matched against those four answers.

02 / FOUR QUESTIONS

Nothing is allowed until a policy says so

Start the SupportRead role with no permissions, then add one statement and get its resource wrong.

STEP 1 OF 3 · Nothing allows it

The role is new and has no policies. Every request starts out denied, and with no Allow anywhere it stays denied. AWS calls this an implicit deny.

A request, the policies that could allow it, and the bucketShown: request, identity policy, bucket policy, decision, reports bucket. request to decision. decision to reports bucket (stopped).

How AWS decides

SupportRead/maya → s3:ListBucket amzn-s3-demo-bucket-reports
  1. Explicit denypassesNo Deny statement matches this request.
  2. SCP on the caller's accountpassesThe organization lets principals in this account use S3. An SCP sets a ceiling; it grants nothing.
  3. Bucket policypassesIt has no statement for this principal. In one account, the identity policy can allow it instead.
  4. Identity policystops hereNo statement in the role's policy allows s3:ListBucket.
  5. Permissions boundarynot reachedNot reached: this account already said no.

DENIEDImplicit deny: no Allow applies to this request.

STEP 2 OF 3 · Add an Allow

One statement in the role's identity policy names the action and the bucket. It matches the request, nothing denies it, and S3 returns the listing.

A request, the policies that could allow it, and the bucketShown: request, identity policy, bucket policy, decision, reports bucket. request to decision. identity policy to decision. decision to reports bucket.

How AWS decides

SupportRead/maya → s3:ListBucket amzn-s3-demo-bucket-reports
  1. Explicit denypassesNo Deny statement matches this request.
  2. SCP on the caller's accountpassesThe organization lets principals in this account use S3. An SCP sets a ceiling; it grants nothing.
  3. Bucket policypassesIt has no statement for this principal. In one account, the identity policy can allow it instead.
  4. Identity policypassesThe role's policy allows s3:ListBucket on amzn-s3-demo-bucket-reports.
  5. Permissions boundarypassesThe role has no boundary, or its boundary includes this action.

ALLOWEDAn Allow applies and nothing denies or caps it.

Identity policy on SupportRead

{  "Version": "2012-10-17",  "Statement": [    {      "Sid": "ReadReports",      "Effect": "Allow",      "Action": "s3:ListBucket",      "Resource": "arn:aws:s3:::amzn-s3-demo-bucket-reports"    }  ]}
STEP 3 OF 3 · Allow the wrong resource

This statement names bucket/*, which means the objects. ListBucket acts on the bucket itself, so the statement doesn't match and the request is denied again.

A request, the policies that could allow it, and the bucketShown: request, identity policy, bucket policy, decision, reports bucket. request to decision. decision to reports bucket (stopped).

How AWS decides

SupportRead/maya → s3:ListBucket amzn-s3-demo-bucket-reports
  1. Explicit denypassesNo Deny statement matches this request.
  2. SCP on the caller's accountpassesThe organization lets principals in this account use S3. An SCP sets a ceiling; it grants nothing.
  3. Bucket policypassesIt has no statement for this principal. In one account, the identity policy can allow it instead.
  4. Identity policystops hereIts Allow names amzn-s3-demo-bucket-reports/*, the objects. s3:ListBucket is checked against the bucket ARN, so the statement doesn't match.
  5. Permissions boundarynot reachedNot reached: this account already said no.

DENIEDImplicit deny: no Allow applies to this request.

Identity policy on SupportRead

{  "Version": "2012-10-17",  "Statement": [    {      "Sid": "ReadReports",      "Effect": "Allow",      "Action": "s3:ListBucket",      "Resource": "arn:aws:s3:::amzn-s3-demo-bucket-reports/*"    }  ]}
INSPECTOR

Implicit deny is the starting point

Every request starts denied. A request runs only if a policy has an Allow statement whose action, resource and condition all match it, and nothing else denies or caps it. A statement that almost matches allows nothing.

Default
Implicit deny
An Allow must match
Action, Resource, Condition
ListBucket resource
arn:aws:s3:::amzn-s3-demo-bucket-reports
GetObject resource
arn:aws:s3:::amzn-s3-demo-bucket-reports/*
TEST WITHOUT CALLING S3aws iam simulate-principal-policy --policy-source-arn arn:aws:iam::222222222222:role/SupportRead --action-names s3:ListBucket --resource-arns arn:aws:s3:::amzn-s3-demo-bucket-reports
WORTH KNOWING

The account root user is the one documented exception to the default deny: it starts with full access to its own account, which is why it should not be used for daily work.

IAM: how requests are allowed or denied ↗S3: policy actions ↗

THE POINT TO KEEPAccess is the exception: with no matching Allow, the answer is no, and an Allow has to match the action and the exact resource form.

03 / FOUR QUESTIONS

A condition decides whether an Allow applies

Add one condition to the Allow: only from the office IP range. Then send the same call from three places.

OPTION 1 OF 4 · From the office

The request comes from 203.0.113.24, inside 203.0.113.0/24. The Condition matches, so the Allow applies.

The same call from three placesShown: office laptop, home laptop, EC2 instance, VPC endpoint, S3. office laptop to S3: internet.

How AWS decides

SupportRead/maya → s3:ListBucket amzn-s3-demo-bucket-reports
  1. Explicit denypassesNo Deny statement matches this request.
  2. SCP on the caller's accountpassesThe organization lets principals in this account use S3. An SCP sets a ceiling; it grants nothing.
  3. Bucket policypassesIt has no statement for this principal. In one account, the identity policy can allow it instead.
  4. Identity policypassesThe role's policy allows s3:ListBucket on amzn-s3-demo-bucket-reports.
  5. Permissions boundarypassesThe role has no boundary, or its boundary includes this action.

ALLOWEDAn Allow applies and nothing denies or caps it.

Identity policy on SupportRead

{  "Version": "2012-10-17",  "Statement": [    {      "Sid": "ReadReports",      "Effect": "Allow",      "Action": "s3:ListBucket",      "Resource": "arn:aws:s3:::amzn-s3-demo-bucket-reports",      "Condition": {        "IpAddress": {          "aws:SourceIp": "203.0.113.0/24"        }      }    }  ]}
OPTION 2 OF 4 · From home

The same credentials from 198.51.100.7. The Condition doesn't match, so that Allow simply doesn't apply. No other Allow exists, so the request is denied.

NOT A DENYA failed Condition switches off its own statement. Another Allow could still grant the call; only a Deny statement blocks it outright.

The same call from three placesShown: office laptop, home laptop, EC2 instance, VPC endpoint, S3. home laptop to S3: internet (stopped).

How AWS decides

SupportRead/maya → s3:ListBucket amzn-s3-demo-bucket-reports
  1. Explicit denypassesNo Deny statement matches this request.
  2. SCP on the caller's accountpassesThe organization lets principals in this account use S3. An SCP sets a ceiling; it grants nothing.
  3. Bucket policypassesIt has no statement for this principal. In one account, the identity policy can allow it instead.
  4. Identity policystops hereIts Allow statement doesn't apply. Its Condition needs aws:SourceIp in 203.0.113.0/24, and this request doesn't match.
  5. Permissions boundarynot reachedNot reached: this account already said no.

DENIEDImplicit deny: no Allow applies to this request.

OPTION 3 OF 4 · Through a VPC endpoint

An EC2 instance in the office VPC reaches S3 through a gateway endpoint. Requests through an endpoint carry no aws:SourceIp, so the IP condition can't match.

The same call from three placesShown: office laptop, home laptop, EC2 instance, VPC endpoint, S3. EC2 instance to VPC endpoint. VPC endpoint to S3: private (stopped).

How AWS decides

SupportRead/maya → s3:ListBucket amzn-s3-demo-bucket-reports
  1. Explicit denypassesNo Deny statement matches this request.
  2. SCP on the caller's accountpassesThe organization lets principals in this account use S3. An SCP sets a ceiling; it grants nothing.
  3. Bucket policypassesIt has no statement for this principal. In one account, the identity policy can allow it instead.
  4. Identity policystops hereIts Allow statement doesn't apply. Its Condition needs aws:SourceIp in 203.0.113.0/24, and this request has no aws:SourceIp because it came through a VPC endpoint.
  5. Permissions boundarynot reachedNot reached: this account already said no.

DENIEDImplicit deny: no Allow applies to this request.

OPTION 4 OF 4 · Match the endpoint instead

For traffic through the endpoint, check the endpoint's ID with aws:SourceVpce. Now the instance's request matches.

The same call from three placesShown: office laptop, home laptop, EC2 instance, VPC endpoint, S3. EC2 instance to VPC endpoint. VPC endpoint to S3: private.

How AWS decides

SupportRead/maya → s3:ListBucket amzn-s3-demo-bucket-reports
  1. Explicit denypassesNo Deny statement matches this request.
  2. SCP on the caller's accountpassesThe organization lets principals in this account use S3. An SCP sets a ceiling; it grants nothing.
  3. Bucket policypassesIt has no statement for this principal. In one account, the identity policy can allow it instead.
  4. Identity policypassesThe role's policy allows s3:ListBucket on amzn-s3-demo-bucket-reports.
  5. Permissions boundarypassesThe role has no boundary, or its boundary includes this action.

ALLOWEDAn Allow applies and nothing denies or caps it.

The condition, rewritten

"Condition": {  "StringEquals": { "aws:SourceVpce": "vpce-0a1b2c3d4e5f60718" }}
INSPECTOR

Conditions read the request context

A Condition is part of the statement that holds it. When a condition key in it doesn't match, or the request doesn't carry that key at all, the statement doesn't apply. With no other Allow, the result is an implicit deny.

aws:SourceIp
public IP; absent through a VPC endpoint
aws:SourceVpce
present only through a VPC endpoint
aws:SecureTransport
whether the request used TLS
Missing key
an ordinary operator doesn't match
READ THE KEY YOUR POLICY NEEDSCloudTrail event → sourceIPAddress, vpcEndpointId
WORTH KNOWING

aws:MultiFactorAuthPresent is only in the context for temporary credentials. AWS recommends a Deny with BoolIfExists set to false, so that requests signed with long-term access keys, which carry no MFA key, are denied too.

IAM: global condition keys ↗S3: bucket policies for VPC endpoints ↗IAM: the request context ↗

THE POINT TO KEEPA condition narrows the statement it sits in; when the request lacks the key or the value differs, that Allow drops out, which is different from being denied.

04 / FOUR QUESTIONS

One Deny beats every Allow, and ceilings cap the rest

The HOW of a decision is more than one policy. Keep the role's Allow in place and change one other policy at a time.

OPTION 1 OF 4 · Every layer allows

No Deny matches, the SCP leaves room for S3, the identity policy allows the call and the role's boundary includes it.

Every layer has to let the request throughShown: request, any Deny?, SCP, an Allow, boundary, bucket. request to any Deny?. any Deny? to SCP. SCP to an Allow. an Allow to boundary. boundary to bucket.

How AWS decides

SupportRead/maya → s3:ListBucket amzn-s3-demo-bucket-reports
  1. Explicit denypassesNo Deny statement matches this request.
  2. SCP on the caller's accountpassesThe organization lets principals in this account use S3. An SCP sets a ceiling; it grants nothing.
  3. Bucket policypassesIt has no statement for this principal. In one account, the identity policy can allow it instead.
  4. Identity policypassesThe role's policy allows s3:ListBucket on amzn-s3-demo-bucket-reports.
  5. Permissions boundarypassesThe role has no boundary, or its boundary includes this action.

ALLOWEDAn Allow applies and nothing denies or caps it.

OPTION 2 OF 4 · A Deny in the bucket policy

The bucket owner protects the bucket: Deny s3:DeleteBucket to every principal. Maya's role allows DeleteBucket, and so does the bucket policy, but one matching Deny ends the evaluation.

Every layer has to let the request throughShown: request, any Deny?, SCP, an Allow, boundary, bucket. request to any Deny?.

How AWS decides

SupportRead/maya → s3:DeleteBucket amzn-s3-demo-bucket-reports
  1. Explicit denystops hereThe bucket policy says Deny s3:DeleteBucket to every principal. One matching Deny ends the evaluation.
  2. SCP on the caller's accountnot reachedNot reached: this account already said no.
  3. Bucket policynot reachedNot reached: this account already said no.
  4. Identity policynot reachedNot reached: this account already said no.
  5. Permissions boundarynot reachedNot reached: this account already said no.

DENIEDExplicit deny: one Deny beats every Allow.

Bucket policy statement

{  "Sid": "NeverDeleteBucket",  "Effect": "Deny",  "Principal": "*",  "Action": "s3:DeleteBucket",  "Resource": "arn:aws:s3:::amzn-s3-demo-bucket-reports"}
OPTION 3 OF 4 · The SCP leaves S3 out

The organization replaced FullAWSAccess on this account with an SCP that allows only EC2 and CloudWatch. The role's own Allow can't reach past that ceiling.

Every layer has to let the request throughShown: request, any Deny?, SCP, an Allow, boundary, bucket. request to any Deny?. any Deny? to SCP.

How AWS decides

SupportRead/maya → s3:ListBucket amzn-s3-demo-bucket-reports
  1. Explicit denypassesNo Deny statement matches this request.
  2. SCP on the caller's accountstops hereThe SCP has no Allow for S3 actions, so nothing in this account can use S3, whatever its own policies say.
  3. Bucket policynot reachedNot reached: this account already said no.
  4. Identity policynot reachedNot reached: this account already said no.
  5. Permissions boundarynot reachedNot reached: this account already said no.

DENIEDImplicit deny: the SCP sets no room for S3.

SCP on account 222…

{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Action": [        "ec2:*",        "cloudwatch:*"      ],      "Resource": "*"    }  ]}
OPTION 4 OF 4 · The boundary leaves it out

The role has a permissions boundary that allows only s3:GetObject. ListBucket is in the identity policy but outside the boundary, so it is denied.

Every layer has to let the request throughShown: request, any Deny?, SCP, an Allow, boundary, bucket. request to any Deny?. any Deny? to SCP. SCP to an Allow. an Allow to boundary.

How AWS decides

SupportRead/maya → s3:ListBucket amzn-s3-demo-bucket-reports
  1. Explicit denypassesNo Deny statement matches this request.
  2. SCP on the caller's accountpassesThe organization lets principals in this account use S3. An SCP sets a ceiling; it grants nothing.
  3. Bucket policypassesIt has no statement for this principal. In one account, the identity policy can allow it instead.
  4. Identity policypassesThe role's policy allows s3:ListBucket on amzn-s3-demo-bucket-reports.
  5. Permissions boundarystops hereThe role's boundary leaves out s3:ListBucket. A boundary caps the role, including grants a bucket policy gives the role.

DENIEDImplicit deny: the boundary caps the role.

INSPECTOR

Grants and ceilings

Identity policies and bucket policies grant. SCPs, permissions boundaries and session policies only set a ceiling: they never grant anything, but an action outside them is denied. A Deny statement in any of these policies overrides every Allow.

Explicit Deny
ends the evaluation
SCP
ceiling for principals in member accounts
Permissions boundary
ceiling for one user or role
Session policy
ceiling for one role session
FIND THE LAYER THAT SAID NOAccessDenied message → "because no … policy allows" or "with an explicit deny in a … policy"
WORTH KNOWING

SCPs don't limit principals in the organization's management account or service-linked roles. Resource control policies (RCPs) are the matching ceiling on resources; they are left out of this example.

IAM: how requests are allowed or denied ↗Organizations: SCPs ↗IAM: session policies and boundaries ↗

THE POINT TO KEEPTo be allowed, a request needs one matching Allow and must fit under every ceiling that applies; one matching Deny anywhere ends it.

05 / FOUR QUESTIONS

Across accounts, both sides must say yes

Maya reads the bucket directly from her DeveloperAccess session in account 111…, without assuming a role. Turn each side's Allow on and off.

OPTION 1 OF 4 · Only the identity policy

Maya's role in 111… allows GetObject on the bucket. Account 222… owns the bucket and hasn't agreed, so the request is denied.

A caller in one account, a bucket in anotherShown: DeveloperAccess, identity policy, reports bucket, bucket policy. DeveloperAccess to reports bucket: GetObject (stopped). identity policy to DeveloperAccess: allows?.

How AWS decides

DeveloperAccess/maya → s3:GetObject amzn-s3-demo-bucket-reports/2026/q3.csv
  1. Caller account 111… · Explicit denypassesNo Deny statement in the caller account's policies.
  2. Caller account 111… · SCP on the caller's accountpassesThe organization lets principals in this account use S3. An SCP sets a ceiling; it grants nothing.
  3. Caller account 111… · Identity policypassesThe role's policy allows s3:GetObject on amzn-s3-demo-bucket-reports/*.
  4. Caller account 111… · Permissions boundarypassesThe role has no boundary, or its boundary includes this action.
  5. Bucket account 222… · Explicit denypassesNo Deny statement matches this request.
  6. Bucket account 222… · Bucket policystops hereIt has no statement for this principal.

DENIEDImplicit deny: across accounts, the bucket policy must allow too.

OPTION 2 OF 4 · Only the bucket policy

Now the bucket policy names DeveloperAccess, but Maya's own account gives her role no Allow. Account 111… says no.

A caller in one account, a bucket in anotherShown: DeveloperAccess, identity policy, reports bucket, bucket policy. DeveloperAccess to reports bucket: GetObject (stopped). bucket policy to reports bucket: allows?.

How AWS decides

DeveloperAccess/maya → s3:GetObject amzn-s3-demo-bucket-reports/2026/q3.csv
  1. Caller account 111… · Explicit denypassesNo Deny statement in the caller account's policies.
  2. Caller account 111… · SCP on the caller's accountpassesThe organization lets principals in this account use S3. An SCP sets a ceiling; it grants nothing.
  3. Caller account 111… · Identity policystops hereNo statement in the role's policy allows s3:GetObject.
  4. Caller account 111… · Permissions boundarynot reachedNot reached: this account already said no.
  5. Bucket account 222… · Explicit denypassesNo Deny statement matches this request.
  6. Bucket account 222… · Bucket policypassesIt allows DeveloperAccess to s3:GetObject.

DENIEDImplicit deny: across accounts, the identity policy must allow too.

OPTION 3 OF 4 · Both allow

AWS evaluates the request once in each account. Both evaluations allow it, so S3 returns the object.

A caller in one account, a bucket in anotherShown: DeveloperAccess, identity policy, reports bucket, bucket policy. DeveloperAccess to reports bucket: GetObject. identity policy to DeveloperAccess: allows?. bucket policy to reports bucket: allows?.

How AWS decides

DeveloperAccess/maya → s3:GetObject amzn-s3-demo-bucket-reports/2026/q3.csv
  1. Caller account 111… · Explicit denypassesNo Deny statement in the caller account's policies.
  2. Caller account 111… · SCP on the caller's accountpassesThe organization lets principals in this account use S3. An SCP sets a ceiling; it grants nothing.
  3. Caller account 111… · Identity policypassesThe role's policy allows s3:GetObject on amzn-s3-demo-bucket-reports/*.
  4. Caller account 111… · Permissions boundarypassesThe role has no boundary, or its boundary includes this action.
  5. Bucket account 222… · Explicit denypassesNo Deny statement matches this request.
  6. Bucket account 222… · Bucket policypassesIt allows DeveloperAccess to s3:GetObject.

ALLOWEDBoth accounts allow the request.

Identity policy on DeveloperAccess (111…)

{  "Version": "2012-10-17",  "Statement": [    {      "Sid": "ReadReports",      "Effect": "Allow",      "Action": "s3:GetObject",      "Resource": "arn:aws:s3:::amzn-s3-demo-bucket-reports/*"    }  ]}

Bucket policy (222…)

{  "Version": "2012-10-17",  "Statement": [    {      "Sid": "ShareReports",      "Effect": "Allow",      "Principal": {        "AWS": "arn:aws:iam::111111111111:role/DeveloperAccess"      },      "Action": "s3:GetObject",      "Resource": "arn:aws:s3:::amzn-s3-demo-bucket-reports/*"    }  ]}
OPTION 4 OF 4 · Same account: one is enough

Compare Maya's SupportRead session, which lives in 222… with the bucket. Inside one account, the bucket policy alone allows the request.

A caller in one account, a bucket in anotherShown: SupportRead, reports bucket, bucket policy. SupportRead to reports bucket: GetObject. bucket policy to reports bucket: allows?.

How AWS decides

SupportRead/maya → s3:GetObject amzn-s3-demo-bucket-reports/2026/q3.csv
  1. Explicit denypassesNo Deny statement matches this request.
  2. SCP on the caller's accountpassesThe organization lets principals in this account use S3. An SCP sets a ceiling; it grants nothing.
  3. Bucket policypassesIt allows SupportRead to s3:GetObject.
  4. Identity policypassesNo statement in the role's policy allows s3:GetObject. The bucket policy already allowed it, so in one account that is enough.
  5. Permissions boundarypassesThe role has no boundary, or its boundary includes this action.

ALLOWEDAn Allow applies and nothing denies or caps it.

INSPECTOR

Two evaluations, one answer

For a cross-account request, AWS evaluates the request in the caller's account, where the identity policy and its ceilings apply, and in the resource's account, where the resource policy applies. It allows the request only if both evaluations allow it.

Caller's account
identity policy, SCP, boundary
Resource's account
bucket policy, RCP
Same account
either an identity or a resource policy can allow
Exceptions
role trust and KMS key policies must name the principal
WHICH ACCOUNT AM I IN?aws sts get-caller-identity --query Account
WORTH KNOWING

This is one of two ways across accounts. The other is the Cross-account view later on this page: assume a role in the bucket's account and act as a principal there.

IAM: cross-account evaluation ↗IAM: how requests are allowed or denied ↗

THE POINT TO KEEPA request that crosses an account boundary needs an Allow on both sides; inside one account, either side can grant it.

06 / FOUR QUESTIONS · INTERACTIVE

Ask the four questions yourself

Set who is asking, what they want, how the policies read and where the call comes from. The trail shows each check in the order AWS documents.

The SupportRead session lists the reports bucket in its own account. Its identity policy allows it, and nothing denies it.

WHO is asking
WHAT they want

on amzn-s3-demo-bucket-reports

HOW the policies read
FROM WHERE it comes

Office range 203.0.113.0/24 · endpoint vpce-0a1b2…

How AWS decides

ALLOWEDAn Allow applies and nothing denies or caps it.

  1. Explicit denypassesNo Deny statement matches this request.
  2. SCP on the caller's accountpassesThe organization lets principals in this account use S3. An SCP sets a ceiling; it grants nothing.
  3. Bucket policypassesIt has no statement for this principal. In one account, the identity policy can allow it instead.
  4. Identity policypassesThe role's policy allows s3:ListBucket on amzn-s3-demo-bucket-reports.
  5. Permissions boundarypassesThe role has no boundary, or its boundary includes this action.

The request context

Principal
arn:aws:sts::222222222222:assumed-role/SupportRead/maya
Action
s3:ListBucket
Resource
arn:aws:s3:::amzn-s3-demo-bucket-reports
aws:PrincipalArn
arn:aws:iam::222222222222:role/SupportRead
aws:PrincipalAccount
222222222222
aws:SourceIp
203.0.113.24
aws:SecureTransport
true

Identity policy on SupportRead (222…)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadReports",
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::amzn-s3-demo-bucket-reports"
    }
  ]
}

Bucket policy on amzn-s3-demo-bucket-reports (222…)

{
  "Version": "2012-10-17",
  "Statement": []
}

INSPECTOR

A model of one S3 decision

The simulator follows AWS's documented order: explicit deny, SCP, bucket policy, identity policy, permissions boundary. For a caller in another account it runs one evaluation per account. It doesn't call AWS.

Left out
RCPs, session policies, ACLs, Block Public Access
Bucket
amzn-s3-demo-bucket-reports
Accounts
111… caller · 222… bucket
CHECK A REAL POLICYaws iam simulate-principal-policy … or IAM Access Analyzer policy checks
WORTH KNOWING

A real anonymous request also has to get past S3 Block Public Access, which is on by default for new buckets.

IAM: how requests are allowed or denied ↗IAM: cross-account evaluation ↗IAM: global condition keys ↗

THE POINT TO KEEPName the principal, action, resource and context first; then look for a Deny, check each ceiling, and find the Allow, in each account the request touches.

07 / CREDENTIAL PIPELINE · INTERACTIVE

From identity to authorized request

Choose a source path, then follow credentials and authorization through six stages.

1

Identity source

Who or what is requesting?

2

Authenticate

Prove the source identity

3

Obtain credentials

Select or exchange for AWS creds

4

Sign the request

AWS credentials on an API call

GET /?list-type=2
Host: s3.amazonaws.com
Authorization: AWS4-HMAC-SHA256
X-Amz-Security-Token: …
5

Authorization

Can this action happen?

✓ Allowed →× Denied ↓
6

AWS resource

Run the permitted action

Common identity flows

Choose a route to see the whole path

More routes 4

IAM user keys · Long-term IAM user keys can sign API requests directly. They do not become temporary just because the request passes an identity stage.

  1. 1IAM userLegacy user in account 111…
  2. 2Access keyKey ID identifies; secret signs locally
  3. 3Current credentialsNo STS exchange in this path
  4. 4SigV4 requestSession token is absent for long-term keys
  5. 5IAM policiesUser and resource policies apply
  6. 6S3 ListBucketAllowed in this fixture

Identity Center · The Identity Center access token obtains AWS role credentials. It is different from the AWS session token that accompanies the resource request.

  1. 1MayaWorkforce identity at an IdP
  2. 2Browser sign-inIdentity Center access token
  3. 3GetRoleCredentialsAssigned account and role
  4. 4AWS role credentialsSigV4 uses AWS session token
  5. 5Evaluate requestAccount-role permission context
  6. 6S3 ListBucketAllowed in this fixture

Cross-account role · AssumeRole and the later S3 request are two authorizations. A valid target session can still be denied at S3.

  1. 1Maya’s role sessionAccount 111… is the caller
  2. 2Signed STS requestSource permission + target trust
  3. 3AssumeRoleSTS issues account 222… session
  4. 4New SupportRead setUse new set for the next request
  5. 5Target-role policiesSeparate resource decision
  6. 6S3 ListBucketAllowed in this fixture

EKS Pod · IRSA · IRSA uses a Kubernetes service account token with STS web identity. EKS Pod Identity uses a different delivery path.

  1. 1Pod service accountIRSA-specific path
  2. 2OIDC tokenToken issuer, audience and subject
  3. 3AssumeRoleWithWebIdentityNo starting AWS key required
  4. 4Role credentialsSDK signs with returned AWS set
  5. 5Pod request policyRole and applicable controls
  6. 6S3 ListBucketAllowed in this fixture

EC2 instance role · The SDK’s EC2 provider supplies temporary credentials. Application code does not need to call AssumeRole for its own instance role.

  1. 1EC2 workloadApplication runs on the instance
  2. 2Instance profileInstance profile associates role
  3. 3IMDS providerSDK retrieves and refreshes a set
  4. 4Role credentialsSDK signs the request
  5. 5Role policiesEvaluate the instance-role session
  6. 6S3 ListBucketAllowed in this fixture

Lambda execution · iam:PassRole can authorize the role association when the function is configured; Lambda later uses the execution role.

  1. 1Lambda functionService runs the function
  2. 2Service trustLambda assumes execution role
  3. 3Runtime credentialsCredentials provided in runtime
  4. 4Execution-role sessionSDK signs resource request
  5. 5Role policiesRole and applicable controls
  6. 6S3 ListBucketAllowed in this fixture

Federated user · SAML · The SAML assertion is the input to the STS exchange; it is not the AWS credential set returned for signing.

  1. 1Workforce userEnterprise IdP authenticates
  2. 2SAML assertionAssertion supplies identity proof
  3. 3AssumeRoleWithSAMLSTS validates assertion and trust
  4. 4Role credentialsAWS set signs later request
  5. 5Role policiesRole and applicable controls
  6. 6S3 ListBucketAllowed in this fixture

Workload · OIDC · A matching token, configured provider and role trust are required. An arbitrary OIDC token grants no AWS access.

  1. 1CI workloadExternal workload identity
  2. 2OIDC identity tokenTrusted issuer, audience, subject
  3. 3AssumeRoleWithWebIdentitySTS validates token and trust
  4. 4Role credentialsAWS set signs later request
  5. 5Role policiesRole and applicable controls
  6. 6S3 ListBucketAllowed in this fixture

S3 denied · The failure is at the later S3 authorization boundary. Reworking the role trust policy would not add s3:ListBucket.

  1. 1Maya’s role sessionSame caller as cross-account path
  2. 2Signed STS requestSource and trust both permit issuance
  3. 3AssumeRole allowedSTS returns target credentials
  4. 4Valid SupportRead setRequest signature is valid
  5. 5S3 denies ListBucketMissing s3:ListBucket in this fixture
  6. 6No listingResource action blocked

Credential example

Fictional values · no live AWS call

aws configure --profile legacy-user
aws sts get-caller-identity --profile legacy-user

# A user access key can sign directly.
# This path has no AWS session token.
# Never paste the secret into a shared script.

For an IAM user with long-term keys, there is no temporary credential exchange in this direct request.

aws sts assume-role \
  --role-arn arn:aws:iam::222222222222:role/SupportRead \
  --role-session-name maya --profile workforce

# Response (fictional values)
Credentials: {
  AccessKeyId: ASIA…DEMO,
  SecretAccessKey: [redacted],
  SessionToken: [redacted],
  Expiration: 2026-10-15T14:32:56Z
}

The caller uses existing AWS credentials for ordinary AssumeRole. The returned set belongs to a new session.

import boto3

# Uses the configured provider chain.
s3 = boto3.client("s3")
response = s3.list_objects_v2(
    Bucket="amzn-s3-demo-bucket-reports"
)

# The provider renews temporary credentials when supported.

The provider selects credentials and may refresh them; application code should not paste a temporary set into its configuration.

aws sts assume-role-with-web-identity \
  --role-arn arn:aws:iam::222222222222:role/ReportReader \
  --role-session-name ci-report \
  --web-identity-token file://token.jwt

# Returns temporary AWS credentials after trust validation.

This exchange accepts a trusted identity token and does not require pre-existing AWS keys.

aws sts assume-role-with-saml \
  --role-arn arn:aws:iam::222222222222:role/ReportReader \
  --principal-arn arn:aws:iam::222222222222:saml-provider/CompanyIdP \
  --saml-assertion [BASE64_ASSERTION]

# Returns temporary AWS credentials.

The SAML assertion is proof supplied by the IdP. The response is an AWS credential set.

The source proves who it is. A provider supplies credentials. The signed request is then authorized for its specific action and resource.

INSPECTOR

From identity to resource

Choose a source path, trace how it obtains or selects credentials, inspect the signed request, and then locate the authorization decision. The same pipeline exposes a direct IAM user path, a workforce Identity Center path, role assumption, and workload federation.

Starting actor
Maya or the selected workload
Resource goal
List the production report bucket
CURRENT CREDENTIAL CONTEXTDepends on selected flow
WORTH KNOWING

A role ARN and a session ARN are identifiers, not credentials. Temporary AWS credentials also differ from an Identity Center access token.

Identity Center: GetRoleCredentials ↗AWS STS: AssumeRole ↗IAM: using temporary credentials ↗IAM: Signature Version 4 ↗IAM: role and role-session principals ↗STS: GetFederationToken ↗IAM: policy evaluation ↗

THE POINT TO KEEPThe source proves who it is. A provider supplies credentials. Each signed request is authorized for its action and resource.

08 / IDENTITY SOURCES

Browser sign-in is the beginning of the credential journey

Start with the workforce profile in account 111111111111. The CLI obtains AWS credentials after the human signs in.

Configuration selects an account and role

  1. 1ProfileCURRENT
  2. 2BrowserNEXT
  3. 3SSO tokenNEXT
  4. 4AWS credentialsNEXT
  5. 5S3 requestNEXT
LOCAL CONFIGURATIONworkforce profile
read
RESULTNo AWS credentials yet
[profile workforce]
sso_session = company
sso_account_id = 111111111111
sso_role_name = DeveloperAccess

[sso-session company]
sso_start_url = https://example.awsapps.com/start
sso_region = ap-south-1
sso_registration_scopes = sso:account:access
Read profile

Configuration selects an account and role

The workforce profile points to an sso-session, an account, and an assigned role. It tells the CLI where to obtain credentials; it contains no AWS secret key.

Credential context
No AWS credentials yet
Acting identity
Not established
Profile
workforce
Account
111111111111

Authenticate Maya through the browser

  1. 1ProfileCOMPLETE
  2. 2BrowserCURRENT
  3. 3SSO tokenNEXT
  4. 4AWS credentialsNEXT
  5. 5S3 requestNEXT
HUMAN AUTHENTICATIONMaya + identity source
sign in
RESULTBrowser authentication in progress
Sign in

Authenticate Maya through the browser

aws sso login starts the configured Identity Center authorization flow. The identity source authenticates Maya. Current CLI v2 uses PKCE by default; device authorization is an explicit alternative.

Credential context
Browser authentication in progress
Acting identity
Maya at the identity source

The CLI holds an Identity Center access token

  1. 1ProfileCOMPLETE
  2. 2BrowserCOMPLETE
  3. 3SSO tokenCURRENT
  4. 4AWS credentialsNEXT
  5. 5S3 requestNEXT
TOKEN CACHEIdentity Center token
authorize API access
RESULTIdentity Center access token
Cache token

The CLI holds an Identity Center access token

A successful login establishes the Identity Center session and tool-managed token cache. That access token is used with Identity Center APIs; it is not the AWS session token used for a SigV4 S3 request.

Credential context
Identity Center access token
Acting identity
Maya’s Identity Center session

GetRoleCredentials returns AWS role credentials

  1. 1ProfileCOMPLETE
  2. 2BrowserCOMPLETE
  3. 3SSO tokenCOMPLETE
  4. 4AWS credentialsCURRENT
  5. 5S3 requestNEXT
CREDENTIAL EXCHANGEGetRoleCredentials
return credential set
RESULTTemporary AWS role credentials
Get credentials

GetRoleCredentials returns AWS role credentials

When a command needs AWS credentials, the CLI provider calls GetRoleCredentials for the selected account and assigned role using the Identity Center access token. AWS returns an access key ID, secret key, session token, and expiration.

Credential context
Temporary AWS role credentials
Acting identity
AWSReservedSSO_DeveloperAccess… / maya

The resource request uses the AWS credential set

  1. 1ProfileCOMPLETE
  2. 2BrowserCOMPLETE
  3. 3SSO tokenCOMPLETE
  4. 4AWS credentialsCOMPLETE
  5. 5S3 requestCURRENT
RESOURCE REQUESTCLI signer
HTTPS
RESULTSigV4 + AWS session token
Sign API call

The resource request uses the AWS credential set

The CLI signs the AWS API request with the selected AWS credentials and includes the AWS session token. Identity Center sign-in and authorization of that resource request are separate decisions.

Credential context
SigV4 + AWS session token
Acting identity
arn:aws:sts::111111111111:assumed-role/AWSReservedSSO_DeveloperAccess_a1b2c3d4e5f67890/maya
INSPECTOR

Configuration selects an account and role

The workforce profile points to an sso-session, an account, and an assigned role. It tells the CLI where to obtain credentials; it contains no AWS secret key.

Profile
workforce
Account
111111111111
CURRENT CREDENTIAL CONTEXTNo AWS credentials yet
WORTH KNOWING

Verified October 15, 2026: CLI v2.22.0 and later default to PKCE. --use-device-code selects device authorization. Cache files are tool-managed.

AWS CLI: configure Identity Center ↗AWS CLI: Identity Center concepts ↗Identity Center: GetRoleCredentials ↗

THE POINT TO KEEPThe Identity Center access token gets role credentials; the AWS session token accompanies the signed AWS request.

09 / IDENTITY SOURCES

Identity Center configures a role inside the account

The group assignment selects who gets access; the permission set describes the account-side role to provision.

A permission set provisions an account-side IAM role

Identity Center configuration

ASSIGNMENTMaya · EngineeringAccount 111111111111 + DeveloperAccess
PERMISSION SETDeveloperAccessPolicies + session settings
⇢provisions

Workforce account · 111…

IAM ROLEAWSReservedSSO_DeveloperAccess…Trust + permissions, managed by Identity Center

Assigned users can request credentials for this account role.

Assignment to account role

A permission set provisions an account-side IAM role

Assigning a user or group to an AWS account through a permission set causes Identity Center to create and manage an AWSReservedSSO_ role in that account. The permission set is a template; the account role supplies the permissions used by its sessions.

Credential context
Configuration creates no credential in your profile
Acting identity
Account-side AWSReservedSSO_ role
Identity Center
Group + account assignment + permission set
AWS account
Managed role, trust and permissions
INSPECTOR

A permission set provisions an account-side IAM role

Assigning a user or group to an AWS account through a permission set causes Identity Center to create and manage an AWSReservedSSO_ role in that account. The permission set is a template; the account role supplies the permissions used by its sessions.

Identity Center
Group + account assignment + permission set
AWS account
Managed role, trust and permissions
CURRENT CREDENTIAL CONTEXTConfiguration creates no credential in your profile
WORTH KNOWING

Removing all assignments for a permission set in an account and assigning it again can change the role’s ARN suffix. Review policies that reference that ARN.

Identity Center: provisioned IAM roles ↗AWS CLI: configure Identity Center ↗

THE POINT TO KEEPThe permission set is the template; an account-side IAM role is what the issued session uses.

10 / IDENTITY SOURCES

Workloads need a credential provider, not a human login

Keep the same report-reading job and change where it runs. Watch what supplies the SDK’s credential set.

An instance profile connects EC2 to its role

RUNS ASEC2 instance
OBTAINS CREDENTIALS VIAIMDS provider
USESSDK → S3Signs with role credentials
Role associationInstance profile
AvoidBaking access keys into the image
EC2

An instance profile connects EC2 to its role

Attach the role through an instance profile. An SDK’s EC2 provider retrieves temporary credentials through Instance Metadata Service; the workload signs requests as that role’s session. IMDS access and instance configuration affect delivery.

Credential context
IMDS → SDK credential provider
Acting identity
ReportWorker session
Role association
Instance profile
Avoid
Baking access keys into the image

Application credentials come from the task role

RUNS ASECS application
OBTAINS CREDENTIALS VIAContainer provider
USESSDK → S3Signs with role credentials
ApplicationTask role
Platform operationsTask execution role
ECS task

Application credentials come from the task role

The container credential provider receives credentials for the task IAM role. The task execution role is a separate role used by ECS for platform work such as image pulls and log delivery; it does not substitute for the application’s task role.

Credential context
Container provider → SDK
Acting identity
ReportTask session
Application
Task role
Platform operations
Task execution role

Lambda supplies execution-role credentials

RUNS ASLambda function
OBTAINS CREDENTIALS VIARuntime provider
USESSDK → S3Signs with role credentials
Trust principallambda.amazonaws.com
Role userFunction workload
Lambda

Lambda supplies execution-role credentials

The service assumes the execution role and supplies temporary credentials to the function runtime. Function code uses the SDK’s normal provider; it does not need to call AssumeRole just to use its own execution role.

Credential context
Runtime credential provider → SDK
Acting identity
ReportFunction execution-role session
Trust principal
lambda.amazonaws.com
Role user
Function workload

A workload token can bootstrap AWS access

RUNS ASOIDC workload
OBTAINS CREDENTIALS VIAWeb identity → STS
USESSDK → S3Signs with role credentials
InputTrusted provider’s identity token
Trust conditionsAudience and subject appropriate to the provider
OIDC workload

A workload token can bootstrap AWS access

AssumeRoleWithWebIdentity validates an identity-provider token against the configured provider and role trust. It does not require pre-existing AWS credentials. Restrict the intended audience and subject; possession of an arbitrary OIDC token grants no AWS role access.

Credential context
OIDC token → STS → AWS credentials
Acting identity
Federated workload role session
Input
Trusted provider’s identity token
Trust conditions
Audience and subject appropriate to the provider
INSPECTOR

An instance profile connects EC2 to its role

Attach the role through an instance profile. An SDK’s EC2 provider retrieves temporary credentials through Instance Metadata Service; the workload signs requests as that role’s session. IMDS access and instance configuration affect delivery.

Role association
Instance profile
Avoid
Baking access keys into the image
CURRENT CREDENTIAL CONTEXTIMDS → SDK credential provider
WORTH KNOWING

Provider support, refresh and precedence vary by SDK and version. IAM user access keys can also sign AssumeRole, but they are not the workforce path shown here.

SDKs: credential providers ↗EC2: roles and instance profiles ↗ECS: task role ↗Lambda: execution role ↗STS: AssumeRoleWithWebIdentity ↗

THE POINT TO KEEPIdentify the workload’s role and provider. An OIDC identity token can bootstrap AWS credentials without an AWS access key.

11 / AUTHENTICATION

The CLI signs the request without sending the secret key

Use SupportRead’s temporary credentials for one header-signed S3 ListObjectsV2 call.

The secret key stays with the signer

Local process

Secret access key
Stays here
Request + signing key
Calculate signature
PROOFSignatureDerived from canonical request data
→HTTPS

On the wire → S3

GET /?list-type=2
Host: amzn-s3-demo-bucket-reports.s3.amazonaws.com
Authorization: AWS4-HMAC-SHA256
  Credential=ASIA…DEMO/…
  SignedHeaders=…
  Signature=[calculated value]
X-Amz-Security-Token: [session token]

Identify the session → evaluate s3:ListBucket.

Sign locally

The secret key stays with the signer

For this header-signed S3 example, the CLI uses the secret access key to derive a signing key and calculate a signature over canonical request data. The access key ID identifies the credential; the AWS session token accompanies temporary credentials. HTTPS protects the exchange. A correct signature does not grant the requested action.

Credential context
Access key ID + signature + session token sent
Acting identity
arn:aws:sts::222222222222:assumed-role/SupportRead/maya
INSPECTOR

The secret key stays with the signer

For this header-signed S3 example, the CLI uses the secret access key to derive a signing key and calculate a signature over canonical request data. The access key ID identifies the credential; the AWS session token accompanies temporary credentials. HTTPS protects the exchange. A correct signature does not grant the requested action.

Starting actor
Maya or the selected workload
Resource goal
List the production report bucket
CURRENT CREDENTIAL CONTEXTAccess key ID + signature + session token sent
WORTH KNOWING

This is SigV4 with temporary credentials over HTTPS. Presigned URLs and services with other authentication schemes are outside this view.

IAM: Signature Version 4 ↗IAM: using temporary credentials ↗

THE POINT TO KEEPThe secret computes the signature locally; the service still needs to authorize the requested action.

12 / ASSUME ROLE · INTERACTIVE

Cross-account access has two separate requests

First ask STS for SupportRead in production. Then use that session to ask S3 for the report listing.

STS issues the target session; S3 allows the request

REQUEST 1STS: AssumeRoleTarget credentials issued
use new credentials
REQUEST 2S3: ListObjectsV2Allowed · reports listed

First blocking boundary: complete

Allowed path

STS issues the target session; S3 allows the request

Maya’s source session signs AssumeRole for SupportRead in production. Caller permission and target-role trust both allow this cross-account request. STS returns a new credential set; the later S3 request uses SupportRead’s session and is authorized separately.

Credential context
New SupportRead credentials
Acting identity
arn:aws:sts::222222222222:assumed-role/SupportRead/maya

The source side does not permit AssumeRole

REQUEST 1STS: AssumeRoleDenied · no target session
path stopped
REQUEST 2S3: ListObjectsV2Not reached

First blocking boundary: AssumeRole

Caller denies

The source side does not permit AssumeRole

The source role’s effective permissions do not allow sts:AssumeRole on SupportRead in this preset. Target trust alone cannot grant this cross-account access. No target credential set is issued.

Credential context
No target credentials issued
Acting identity
Source session remains available

The target role does not trust this caller

REQUEST 1STS: AssumeRoleDenied · no target session
path stopped
REQUEST 2S3: ListObjectsV2Not reached

First blocking boundary: AssumeRole

Trust denies

The target role does not trust this caller

The source side permits AssumeRole, but the target-role trust policy does not admit the source principal in this preset. STS denies session creation, before the production S3 request exists.

Credential context
No target credentials issued
Acting identity
Source session remains available

AssumeRole succeeds; the resource request fails

REQUEST 1STS: AssumeRoleTarget credentials issued
use new credentials
REQUEST 2S3: ListObjectsV2Denied · valid credentials

First blocking boundary: S3 request

S3 denies

AssumeRole succeeds; the resource request fails

STS issues SupportRead credentials, but the later S3 ListBucket request is denied in this preset. Investigate the session’s resource permissions and applicable policies; changing who can assume the role does not itself grant ListBucket.

Credential context
Valid SupportRead credentials
Acting identity
arn:aws:sts::222222222222:assumed-role/SupportRead/maya
INSPECTOR

STS issues the target session; S3 allows the request

Maya’s source session signs AssumeRole for SupportRead in production. Caller permission and target-role trust both allow this cross-account request. STS returns a new credential set; the later S3 request uses SupportRead’s session and is authorized separately.

Starting actor
Maya or the selected workload
Resource goal
List the production report bucket
CURRENT CREDENTIAL CONTEXTNew SupportRead credentials
WORTH KNOWING

These four presets isolate documented boundaries; they do not run AWS’s complete policy engine. Same-account direct trust has additional identity-policy nuances. Other applicable policies can still deny access.

AWS STS: AssumeRole ↗IAM: cross-account evaluation ↗IAM: session policies and boundaries ↗

THE POINT TO KEEPPermission to create a role session and permission to use a resource are different decisions.

13 / ASSUME ROLE

A second role starts a new permission context

The workforce session is already a role session, so its AssumeRole request to production is role chaining.

Role credentials assuming a role is role chaining

SOURCE SESSIONDeveloperAccessExisting role credentials
STS REQUESTDurationSeconds = 3600Target role max: 4 hours (example)
RESULTNew SupportRead session1 hour maximum
15 min1 hour cap2 hours requested

Source permissions stay with the source session. They are not added to SupportRead.

Request 1 hour

Role credentials assuming a role is role chaining

The Identity Center role session in the workforce account calls AssumeRole for SupportRead. This is role chaining: the resulting session is limited to one hour even if SupportRead permits a longer maximum. The new session uses target-role permissions rather than a union with the source role.

Credential context
SupportRead session · up to 1 hour here
Acting identity
arn:aws:sts::222222222222:assumed-role/SupportRead/maya

A longer role maximum does not extend a chained session

SOURCE SESSIONDeveloperAccessExisting role credentials
STS REQUESTDurationSeconds = 7200Target role max: 4 hours (example)
RESULTRequest rejectedChaining limit exceeded
15 min1 hour cap2 hours requested

Source permissions stay with the source session. They are not added to SupportRead.

Request 2 hours

A longer role maximum does not extend a chained session

A DurationSeconds value of 7200 exceeds the one-hour role-chaining limit, so this request fails. This does not mean all temporary credentials last one hour: the limit here follows the role-to-role path.

Credential context
No new credential set
Acting identity
Source session remains the caller
INSPECTOR

Role credentials assuming a role is role chaining

The Identity Center role session in the workforce account calls AssumeRole for SupportRead. This is role chaining: the resulting session is limited to one hour even if SupportRead permits a longer maximum. The new session uses target-role permissions rather than a union with the source role.

Starting actor
Maya or the selected workload
Resource goal
List the production report bucket
CURRENT CREDENTIAL CONTEXTSupportRead session · up to 1 hour here
WORTH KNOWING

Verified October 15, 2026: AssumeRole has a 15-minute minimum; a role’s configured maximum can be 1–12 hours. A chained session is capped at one hour. Resource-policy grants and other controls need their own evaluation.

AWS STS: AssumeRole ↗AWS CLI: role profiles ↗IAM: session policies and boundaries ↗

THE POINT TO KEEPRole chaining creates separate credentials with a one-hour maximum; source permissions do not accumulate into the new session.

14 / AUTHORIZATION

Who should receive the role’s credentials?

Compare Maya using a role herself with Maya configuring a Lambda function to use an execution role.

The caller receives credentials for its own next request

CALLERMaya’s CLI
signed request
APISTS AssumeRoleChecks permission + trust
credential response
RECEIVERMaya’s CLIReceives temporary credentials
AssumeRole

The caller receives credentials for its own next request

An authorized caller sends an STS AssumeRole request and receives temporary credentials. That caller chooses the returned set to sign a later AWS request.

Credential context
Returned to the calling application
Acting identity
Caller uses the resulting role session

The service uses the execution role later

CALLERMaya configures LambdaCreateFunction with execution role
service API
AUTHORIZATIONiam:PassRole checkPart of the service API decision
service execution
ROLE USERLambda serviceLater assumes its execution role
PassRole

The service uses the execution role later

When Maya creates a Lambda function with a role ARN, iam:PassRole is checked as part of the service API authorization. PassRole is not an API operation and returns no credentials. Lambda must be trusted by the role; the passed role and Lambda function are in the same account.

Credential context
None returned by PassRole
Acting identity
Lambda later uses the execution-role session
INSPECTOR

The caller receives credentials for its own next request

An authorized caller sends an STS AssumeRole request and receives temporary credentials. That caller chooses the returned set to sign a later AWS request.

Starting actor
Maya or the selected workload
Resource goal
List the production report bucket
CURRENT CREDENTIAL CONTEXTReturned to the calling application
WORTH KNOWING

Scope iam:PassRole to approved role ARNs and, where appropriate, iam:PassedToService. Audit the service API event, such as CreateFunction; there is no separate PassRole API event.

IAM: PassRole ↗Lambda: execution role ↗

THE POINT TO KEEPAssumeRole returns credentials to the caller. PassRole authorizes a service-role association.

15 / ACROSS ACCOUNTS

ExternalId binds the deputy to the customer

A reporting vendor serves several customers. Each customer trusts the vendor, but only for the expected tenant context.

The vendor selects the customer’s configured external ID

AUTHENTICATED TENANTReports customerVendor selects: tenant-reports-42
REPORTS ROLE TRUSTTrusted vendor principalRequires ExternalId = tenant-reports-42
REQUESTAssumeRoleExternalId: tenant-reports-42
RESULTTenant binding matchesCustomer credentials issued
Reports tenant

The vendor selects the customer’s configured external ID

The vendor authenticates the reports customer, then obtains its configured role ARN and vendor-generated external ID from the tenant record. The target trust requires the trusted vendor principal and the matching external ID.

Credential context
Customer-role credentials issued
Acting identity
Vendor session in the customer account

Knowing the role ARN does not select its external ID

AUTHENTICATED TENANTOther customerVendor selects: tenant-other-17
REPORTS ROLE TRUSTTrusted vendor principalRequires ExternalId = tenant-reports-42
REQUESTAssumeRoleExternalId: tenant-other-17
RESULTTenant binding failsSTS denies this request
Other tenant

Knowing the role ARN does not select its external ID

Another vendor customer supplies the reports role ARN. The vendor still chooses the external ID from the authenticated other-tenant record. The mismatch fails the customer role’s trust condition. An external ID is a tenant-binding value, not a password or a substitute for vendor authentication.

Credential context
No customer-role credentials issued
Acting identity
Vendor’s starting session
INSPECTOR

The vendor selects the customer’s configured external ID

The vendor authenticates the reports customer, then obtains its configured role ARN and vendor-generated external ID from the tenant record. The target trust requires the trusted vendor principal and the matching external ID.

Starting actor
Maya or the selected workload
Resource goal
List the production report bucket
CURRENT CREDENTIAL CONTEXTCustomer-role credentials issued
WORTH KNOWING

The vendor generates and controls a unique ExternalId per customer. It is not a secret, a password, or a replacement for the vendor principal and scoped permissions.

IAM: confused deputy and ExternalId ↗AWS STS: AssumeRole ↗

THE POINT TO KEEPThe vendor chooses ExternalId from its authenticated tenant record; a customer-supplied role ARN alone cannot choose the tenant.

16 / SERVICES & USE CASES

An upstream login and AWS credentials have different clocks

Distinguish refreshing a provider from keeping an exported access-key snapshot in a shell.

Refresh replaces a credential set before it expires

Illustrative timing · each row has its own expiration

Identity Center sessionUsable upstream authorization
AWS credential set AIssued ───────── expires
AWS credential set BProvider obtains a fresh set →
Provider refreshes

Refresh replaces a credential set before it expires

A configured refresh-capable provider obtains a fresh AWS credential set while its upstream authorization remains usable. The old access key and expiration do not mutate. Identity Center tokens and account-role credentials have separate validity periods.

Credential context
New credential set replaces the selected set
Acting identity
A session of the selected account role

A copied credential set has no refresh mechanism

Illustrative timing · each row has its own expiration

Identity Center sessionUsable upstream authorization
AWS credential set AIssued ───────── expires
AWS credential set BNo provider: copied snapshot
Exported snapshot

A copied credential set has no refresh mechanism

Copying access key, secret key, and session token into environment variables gives the process a snapshot. It does not copy the original provider’s refresh behavior. When those credentials expire, obtain a new set or use the provider directly.

Credential context
Expired exported credential snapshot
Acting identity
Expired session credentials

An upstream session can stop future refresh

Illustrative timing · each row has its own expiration

Identity Center sessionUpstream session unusable
AWS credential set AIssued ───────── expires
AWS credential set BRefresh needs sign-in
Sign-in required

An upstream session can stop future refresh

If the Identity Center session is no longer usable, the provider cannot keep obtaining account-role credentials; the CLI can require aws sso login. Browser or SSO logout is not an instant revocation mechanism for every already-issued AWS role credential.

Credential context
Refresh blocked at upstream session
Acting identity
Earlier AWS credentials have their own expiry
INSPECTOR

Refresh replaces a credential set before it expires

A configured refresh-capable provider obtains a fresh AWS credential set while its upstream authorization remains usable. The old access key and expiration do not mutate. Identity Center tokens and account-role credentials have separate validity periods.

Starting actor
Maya or the selected workload
Resource goal
List the production report bucket
CURRENT CREDENTIAL CONTEXTNew credential set replaces the selected set
WORTH KNOWING

Timeline lengths are illustrative, not service defaults. Reauthentication, credential expiration and revocation are separate mechanisms; do not treat logout as immediate revocation of every issued session.

AWS CLI: Identity Center concepts ↗IAM: using temporary credentials ↗SDKs: credential providers ↗AWS CLI: role profiles ↗

THE POINT TO KEEPA provider obtains a new credential set. It does not extend the lifetime of the old one.

17 / ACROSS ACCOUNTS

Trace the request back through the role session

Read the session ARN, the issuing role and optional attribution context without mistaking a label for proof of a person.

The role ARN names configuration; the session ARN names the acting principal

{
  "userIdentity": {
    "type": "AssumedRole",
    "arn": "arn:aws:sts::222222222222:assumed-role/SupportRead/maya",
    "sessionContext": {
      "sessionIssuer": {
        "type": "Role",
        "arn": "arn:aws:iam::222222222222:role/SupportRead"
      },
      "sourceIdentity": "maya@example.com"
    }
  }
}
arn
The session making this request.
sessionIssuer.arn
The role that defines its permission context.
sourceIdentity
Optional origin, constrained at issuance. This field is illustrative.
Follow the session

The role ARN names configuration; the session ARN names the acting principal

CloudTrail records the assumed-role identity and session issuer for resource requests. A session name is useful context, not independently verified human identity. SourceIdentity can preserve an origin across role chaining when configured; session tags carry attributes, with only transitive tags persisting through chaining.

Credential context
Temporary session credentials
Acting identity
arn:aws:sts::222222222222:assumed-role/SupportRead/maya
SourceIdentity
Needs sts:SetSourceIdentity and constrained values
Session tags
Need sts:TagSession; constrain allowed keys and values
INSPECTOR

The role ARN names configuration; the session ARN names the acting principal

CloudTrail records the assumed-role identity and session issuer for resource requests. A session name is useful context, not independently verified human identity. SourceIdentity can preserve an origin across role chaining when configured; session tags carry attributes, with only transitive tags persisting through chaining.

SourceIdentity
Needs sts:SetSourceIdentity and constrained values
Session tags
Need sts:TagSession; constrain allowed keys and values
CURRENT CREDENTIAL CONTEXTTemporary session credentials
WORTH KNOWING

Prefer role principals in policies where practical. Direct grants to role-session principals have different interactions with implicit denies from boundaries and session policies; use the authorization explorer for that decision.

IAM: source identity ↗IAM: session tags ↗IAM: role and role-session principals ↗IAM: session policies and boundaries ↗

THE POINT TO KEEPAudit the acting session and its issuer. Constrain the context that callers are allowed to attach.

18 / SERVICES & USE CASES · INTERACTIVE

Find the first credential boundary that failed

Choose a symptom, then reveal the evidence one check at a time. These are deterministic teaching transcripts, not live AWS calls.

Inspect the credentials selected by this process

Check 1

$ aws configure list
access_key    ****************DEMO    env
secret_key    ****************DEMO    env

The winning source is the environment in this fixture; do not print the secrets.

Check 2

$ aws sts get-caller-identity
Account: 111111111111
Arn: arn:aws:iam::111111111111:user/legacy-build

The request used the legacy user, not SupportRead. Check the process environment and choose the intended profile.

Verify provider → identify caller → locate failed request → narrow permissions → retest and inspect CloudTrail.

Wrong principal

Inspect the credentials selected by this process

In this fixture the command omitted --profile and environment credentials won over the profile selected through AWS_PROFILE. Inspect provider selection and the actual caller before editing production trust.

Credential context
Environment credentials selected
Acting identity
arn:aws:iam::111111111111:user/legacy-build

The target session was never created

Check 1

$ aws sts get-caller-identity --profile workforce
Account: 111111111111
Arn: …assumed-role/AWSReservedSSO_DeveloperAccess_a1b2c3d4e5f67890/maya

The intended source session is active.

Check 2

$ aws sts assume-role --profile workforce --role-arn arn:aws:iam::222222222222:role/SupportRead --role-session-name maya
AccessDenied on sts:AssumeRole
Fixture finding: target trust excludes this source role.

Review caller permission, target trust, conditions and applicable guardrails. The API error alone does not prove which policy failed.

Verify provider → identify caller → locate failed request → narrow permissions → retest and inspect CloudTrail.

AssumeRole denied

The target session was never created

This fixture has valid source credentials but fails at target-role trust. Start with the actual caller, then inspect both sides of this cross-account exchange and its conditions. This is distinct from failure of the later S3 request.

Credential context
Source credentials only
Acting identity
arn:aws:sts::111111111111:assumed-role/AWSReservedSSO_DeveloperAccess_a1b2c3d4e5f67890/maya

Valid credentials do not prove permission to list the bucket

Check 1

$ aws sts get-caller-identity --profile prod-read
Account: 222222222222
Arn: arn:aws:sts::222222222222:assumed-role/SupportRead/maya

The target session is selected. GetCallerIdentity does not test S3 permission.

Check 2

$ aws s3api list-objects-v2 --bucket amzn-s3-demo-bucket-reports --profile prod-read
AccessDenied on ListObjectsV2
IAM permission required: s3:ListBucket on the bucket ARN

Inspect role/session permissions, applicable boundaries, Organizations controls, resource policy and request context.

Verify provider → identify caller → locate failed request → narrow permissions → retest and inspect CloudTrail.

S3 denied

Valid credentials do not prove permission to list the bucket

The target role session exists in production, but ListBucket is denied. The identity flow has succeeded; investigate the resource authorization decision with the correct action and bucket ARN.

Credential context
Valid SupportRead credentials
Acting identity
arn:aws:sts::222222222222:assumed-role/SupportRead/maya

Find the provider that can obtain a fresh set

Check 1

$ aws sts get-caller-identity
ExpiredToken: the security token included in the request is expired

Locate the expired credential source rather than treating this as a permission denial.

Check 2

$ aws configure list
access_key    ****************DEMO    env
secret_key    ****************DEMO    env

Remove the stale snapshot from this process and use the configured provider; sign in again if its upstream session requires it.

Verify provider → identify caller → locate failed request → narrow permissions → retest and inspect CloudTrail.

Expired credentials

Find the provider that can obtain a fresh set

A process using an exported snapshot reaches its credential expiration. Changing the target role’s trust policy cannot refresh those environment values.

Credential context
Expired environment snapshot
Acting identity
No current usable session credentials

Temporary credentials include a session token

Check 1

$ Inspect credential configuration without printing values
AWS_ACCESS_KEY_ID: set
AWS_SECRET_ACCESS_KEY: set
AWS_SESSION_TOKEN: missing

The temporary credential tuple is incomplete. Exact service error wording varies.

Check 2

$ Use a configured refresh-capable provider
Provider supplies access key ID + secret key + session token + expiration

The credential provider should supply and refresh the complete set.

Verify provider → identify caller → locate failed request → narrow permissions → retest and inspect CloudTrail.

Incomplete set

Temporary credentials include a session token

An access key ID and secret alone are incomplete for this temporary session. Keep all three credential values from the same issuance; do not combine values from different sessions.

Credential context
Session token missing
Acting identity
Temporary session cannot authenticate correctly
INSPECTOR

Inspect the credentials selected by this process

In this fixture the command omitted --profile and environment credentials won over the profile selected through AWS_PROFILE. Inspect provider selection and the actual caller before editing production trust.

Starting actor
Maya or the selected workload
Resource goal
List the production report bucket
CURRENT CREDENTIAL CONTEXTEnvironment credentials selected
WORTH KNOWING

Exact AWS error wording varies. A generic AccessDenied does not identify a single failing policy. GetCallerIdentity identifies the caller and does not prove S3 permission.

AWS CLI: configuration precedence ↗STS: GetCallerIdentity ↗AWS CLI: configure list ↗IAM: cross-account evaluation ↗

THE POINT TO KEEPFirst verify the provider and actual caller; then separate issuance failure from resource authorization failure.