How AWS decides allow or deny
The order AWS checks policy types in, which layers grant and which only cap, the same-account and cross-account rules, and the exceptions (resource-policy principal types, management account, service-linked roles) that make a correct-looking policy fail.
markdownreferencev49C8N-8K9Xstage: referencetrust: officialservice: iamservice: organizationsinterface: anypolicy evaluationevaluation logicexplicit denyimplicit denypermissions boundarySCPRCPsession policyresource-based policycross-accounteffective permissions
Three rules decide almost every case. Everything is denied unless something allows it. An explicit Deny in any applicable policy beats every Allow. And only two policy types grant (identity-based and resource-based policies); every other type only caps: SCPs, RCPs, permissions boundaries, session policies and VPC endpoint policies can take an allow away but can never create one.
The order of checks (one account)
AWS evaluates every applicable policy against the request. The single-account order, and where it stops:
| Step | Policy type | Explicit Deny | No applicable Allow | Allow |
|---|---|---|---|---|
| 0 | Any policy (all types below) | Deny, stop | — | — |
| 1 | Resource control policies (RCPs) | (handled in step 0) | Deny, stop | continue |
| 2 | Service control policies (SCPs) | (step 0) | Deny, stop | continue |
| 3 | Resource-based policy | (step 0) | continue (see below) | may allow, stop (see below) |
| 4 | Identity-based policies | (step 0) | Deny, stop | continue |
| 5 | Permissions boundary, if one is set | (step 0) | Deny, stop | continue |
| 6 | Session policy, if the caller is a session | (step 0) | Deny, stop | Allow |
Notes on the steps:
- Step 1. When RCPs are enabled,
RCPFullAWSAccessis attached everywhere and cannot be detached, so this step only refuses when someone wrote a narrowing RCP. - Step 2.
FullAWSAccessis attached by default. Removing it without a replacement Allow makes every action in the affected member accounts fail. - Step 6. An IAM user (not a session) is allowed at this point. A role session with no session policy passed is allowed. A session whose session policy does not allow the action is denied.
- The root user of an account is not subject to implicit denies within its own account, but a member account's root user is subject to SCPs.
How layers combine
| Combination | Effective permission |
|---|---|
| Identity-based + resource-based, same account | Union: either one allowing is enough |
| Identity-based + permissions boundary | Intersection: both must allow |
| Identity-based + SCP + RCP (no resource policy) | Intersection: all three must allow |
| Role's identity policies + session policy | Intersection: the session gets only what both allow |
| Any layer + VPC endpoint policy (request through the endpoint) | The endpoint policy must also allow; it never grants |
A boundary, SCP, RCP or session policy that "allows everything" grants nothing. A user or role with no identity-based policy has no access even when every cap is wide open.
The resource-based policy exceptions
Same account, a resource-based policy can allow on its own, but what the policy names as Principal changes which caps still apply:
| Principal named in the resource policy | Limited by the caller's permissions boundary or session policy? |
|---|---|
Role ARN (arn:aws:iam::<acct>:role/<name>) | Yes |
Assumed-role session ARN (arn:aws:sts::<acct>:assumed-role/<role>/<session>) | No |
| IAM user ARN | No (a user has no session policy) |
| STS federated-user ARN | No |
The IAM user who called GetFederationToken (for that session's requests) | Yes |
"*" with an aws:PrincipalArn condition | No, unless an identity-based policy has an explicit Deny |
Two resource policy types never follow the "either side is enough" rule: role trust policies and KMS key policies must explicitly allow the principal. Some other services also require it; check the service's own documentation.
A trust policy that names a role or user by ARN is stored against that entity's unique ID. Delete and recreate the entity and the trust breaks; the policy shows an ID starting AROA or AIDA until you re-enter the ARN. A condition on aws:PrincipalArn is not converted to an ID and survives recreation.
Cross-account requests
AWS evaluates the request in both accounts and allows it only if both allow:
- Caller's account: the caller's identity-based policy must allow the action on the target ARN, within the caller's SCPs, boundary and session policy.
- Resource's account: the resource-based policy must name the caller (or the caller's account) and allow the action, within that account's RCPs.
Naming an account as principal ("AWS": "111122223333" or the account's :root ARN, which are equivalent) only makes that account eligible; its own administrators decide which identities may use the grant.
Roles are the other cross-account path. The role's trust policy decides who may assume it; after AssumeRole, the caller acts inside the role's account, so access to that account's resources is governed by the role's own identity-based policies, and no per-resource policy is needed.
What the organization layers do not touch
| Not restricted | By SCPs | By RCPs |
|---|---|---|
| Users, roles and resources in the management account | ✓ (SCPs don't affect the management account) | ✓ (RCPs don't affect management-account resources) |
| Service-linked roles | ✓ | ✓ (including the service assuming its SLR) |
| AWS managed KMS keys | — | ✓ |
| Principals in accounts outside the organization | ✓ (SCPs apply only to the organization's own principals) | ✗ — RCPs do apply to outsiders calling a resource inside the organization |
SCPs cap principals in member accounts (including the member root user and delegated administrators). RCPs cap resources in member accounts, for whoever calls them, and only for the services that support RCPs: see reference/organizations/scps-and-rcps.md.
Using this when a request fails
The error message names one refusing policy type; map it to the step above and read only that layer first. The procedure is guides/iam/fix-access-denied.md; the message-by-message causes are in reference/iam/errors.md.