IAM's Policy Evaluation Logic
Every AWS SDK call that touches a permission ends the same way: IAM answers "allow" or "deny."
Busca en todas las páginas de la documentación
Every AWS SDK call that touches a permission ends the same way: IAM answers "allow" or "deny."
That answer looks binary, but it comes from combining several independent policy types, each of which can veto the request.
Understanding the order and logic behind that combination is the single most useful mental model for debugging AccessDenied errors and for reasoning about what a role can actually do.
At its core, IAM evaluation has one governing rule: everything is denied by default.
An IAM principal (user, role, or federated identity) starts with zero permissions.
A request is only allowed if some policy explicitly grants it, and no policy explicitly denies it.
That gives three possible outcomes for any single action: explicit Deny, explicit Allow, or implicit Deny (nothing said anything).
The evaluation logic follows a strict precedence:
Deny matching the action, the request is denied. Full stop.Allow, and every other applicable policy type also allows (or stays silent), the request is allowed.The phrase "explicit Deny always wins" is the one rule worth memorizing above all others.
It means you cannot out-Allow a Deny by attaching a broader policy elsewhere - the Deny is absolute.
The tricky part isn't the precedence order itself, it's that a single request can be governed by up to five different policy types simultaneously, and each is evaluated independently:
sts:AssumeRole), further restricting the session's permissions below what the role itself allows.Every one of these that applies to a given request must agree the action is allowed - a single "no" from any of them produces a Deny.
Think of it as an AND across policy types, but an OR-then-check-for-Deny within each type:
identity-based (Allow?) AND resource-based (Allow or N/A?)
AND boundary (Allow?) AND SCP (Allow?) AND session policy (Allow or N/A?)
AND no explicit Deny anywhere
= final decisionA boundary or an SCP can never grant permission by itself - both are pure ceilings.
If a role's identity-based policy allows s3:PutObject but the boundary does not mention S3 at all, the boundary's own implicit Deny blocks the call, even though nothing explicitly denied it.
This is the single most common surprise for teams new to delegated administration: adding an Allow to a role does nothing if a boundary or SCP above it doesn't also permit that action.
Cross-account access complicates the picture further, because the evaluation runs twice - once in the calling principal's account, once in the resource owner's account (if a resource-based policy is in play).
For a cross-account S3 read, both the caller's identity-based policy (in Account A) and the bucket policy (in Account B) must allow the action; if either says no, the read fails.
SCPs only apply within the organization that manages the account - they have no effect on principals from outside accounts, since they cap what the account itself can permit, not what other accounts can do.
Session policies matter most for temporary-credential patterns: a broker service that hands out scoped-down AssumeRole sessions relies entirely on this layer to keep a session's actual permissions narrower than the role's full policy.
| Layer | Grants Permissions? | Scope | Common Use |
|---|---|---|---|
| Identity-based policy | Yes | One user/role | Day-to-day permission grants |
| Resource-based policy | Yes | One resource | Cross-account access without role assumption |
| Permission boundary | No (ceiling only) | One user/role | Delegated admin safety cap |
| SCP | No (ceiling only) | Account/OU | Org-wide guardrails |
| Session policy | No (narrows only) | One STS session | Scoped temporary credentials |
Debugging a real denial means walking this table for the specific principal and resource involved, not just re-reading the one policy you remember writing.
AWS's own Policy Simulator and IAM Access Analyzer's reachability tooling both exist specifically because this multi-layer evaluation is hard to trace by hand.
The explicit Deny always wins, regardless of how many other policies allow the action. There are no exceptions to this rule anywhere in the evaluation.
It falls to the implicit Deny - the default state for every IAM principal. Silence is not permission; something must explicitly allow the action.
They're similar in that both are pure ceilings, never grants. The difference is scope: a boundary applies to one user or role, an SCP applies to an entire account or organizational unit.
Something else in the stack is still saying no - most often a permission boundary or SCP that doesn't cover the new action, or a resource-based policy on the target that hasn't been updated.
No. The calling principal's own identity-based policy must also allow the action; both the caller's account and the resource owner's account are evaluated independently.
No. SCPs only apply within the AWS Organization that manages the account, capping what that account's own principals can be granted - they have no jurisdiction over outside accounts.
An inline policy passed as a parameter during sts:AssumeRole, further restricting the temporary session below the role's own permissions. It's useful for brokers issuing scoped-down, short-lived credentials.
Yes. SCPs apply to every principal in the account, including the root user - that's part of what makes them effective as an org-wide guardrail.
Up to five: identity-based, resource-based, permission boundary, SCP, and session policy. Not all apply to every request - resource-based and session policies are situational.
Because each account evaluates its own applicable policies independently. The caller's account checks the caller's identity-based policy and any relevant SCP; the resource owner's account checks its resource-based policy and its own SCP.
Use IAM's Policy Simulator or Access Analyzer's policy checks to evaluate the specific action and resource against the actual principal, rather than re-reading policies by eye - the tooling accounts for every layer at once.
Yes. Attaching an explicit Deny for a specific action in an identity-based or resource-based policy overrides any Allow granted elsewhere, including from a managed policy you didn't write.
Stack versions: This page is conceptual and not tied to a specific stack version.
Revisado por Chris St. John·Última actualización: 25 jul 2026