Principals, Policies, and Policy Evaluation
Goal
Turn the high-level IAM model into a clear explanation of how AWS calculates effective permission.
This section centers on one durable idea:
Effective permission comes from how AWS evaluates principals, policies, and explicit boundaries together.
The Short Version
In AWS, a policy document is not the same thing as access.
Access is the result of evaluation. AWS looks at the principal, the request context, and the applicable policy types together. Some policy types add possible permission, some constrain it, and any explicit deny wins.
Request
-> identify principal
-> collect applicable policies
-> evaluate conditions and context
-> check explicit denies
-> calculate final allow or deny
That is why teams get surprised by IAM. They read one policy in isolation and assume they understand the result, when the real answer depends on all applicable policy layers.
What Counts as a Principal
A principal is the identity that makes a request. In this chapter, the most useful principal types are:
| Principal type | What it usually means in practice |
|---|---|
| IAM user | A long-lived identity inside one AWS account. Still supported, but AWS guidance increasingly pushes human access toward federation and temporary credentials. |
| IAM role | An assumable identity with attached permissions and no long-lived credentials of its own. |
| Role session | The temporary session that exists after someone or something assumes a role. |
| Federated session | A session created for a user authenticated by an external identity provider through SAML or OIDC patterns. |
| AWS service principal | An AWS service acting through a trusted role, such as Lambda or EC2 using a role. |
IAM groups matter too, but groups are for permissions management, not authentication. A group helps attach permissions to many IAM users, but a group itself is not the principal making the request.
How to Read a Policy
Most IAM policies are JSON documents, but the architecture meaning is simpler than the syntax:
Actionsays what operation is being requested.Resourcesays which target the statement applies to.Effectsays allow or deny.Conditionnarrows the statement to a specific context.
Identity-based policies are attached to users, groups, or roles and describe what that identity may do. Resource-based policies are attached directly to a resource and describe who may access it. We will use resource-based policies more deeply in the next section, but they already matter here because AWS can evaluate them alongside identity-based policies.
The Practical Evaluation Model
AWS documentation describes evaluation as a sequence: authenticate the principal if needed, build the request context, then evaluate all applicable policy types.
For day-to-day reasoning, four rules get you most of the way:
Everything starts denied unless something allows it.
An explicit deny overrides an allow.
Multiple allow sources may combine in some cases.
Guardrails such as boundaries and organization controls can narrow the result.
The most useful pattern to remember is this:
| Policy relationship | Practical result |
|---|---|
| Identity-based policy plus resource-based policy in the same account | Usually a union of allowed permissions. If either allows the request, AWS can allow it, unless an explicit deny exists. |
| Identity-based policy plus permissions boundary | Intersection. The boundary limits what the identity policy can grant. |
| Identity-based policy plus Organizations SCP | Intersection. The request must survive both. |
| Any applicable explicit deny | Deny wins. |
This is the reason "I attached AdministratorAccess" is not a complete explanation of access. Other layers may still block the request.
Example: Why a Broad Policy Still Fails
Suppose a developer can read logs in a shared observability account but cannot modify production infrastructure, even though one attached policy looks broad.
The real explanation may be:
the identity policy allows broad read access,
the production role trust path is separate,
an SCP prevents infrastructure changes outside approved accounts,
or a condition requires MFA or a specific session path.
The practical lesson is that reviewers should debug access by tracing the full request path, not by reading one policy title.
How to Debug Unexpected Access
When a request behaves differently than expected, inspect:
Which principal actually made the request.
Whether the request used a direct user, a role, or an assumed-role session.
Which identity-based policies applied.
Whether a resource-based policy also applied.
Whether a permissions boundary, session policy, or SCP limited the session.
Whether a condition such as MFA, tags, region, or source network changed the result.
This approach is calmer and faster than arguing about one JSON document.
Common Mistakes
Reading one attached policy and assuming it represents effective permission.
Forgetting that role sessions, not just role names, matter during evaluation.
Ignoring conditions and explicit denies.
Mixing human and workload access into one permission shape because the actions look similar.
If Someone Asks You
Why does a policy that looks broad still not guarantee access?
A good answer is:
Because AWS evaluates the whole request, not one policy file. Identity-based policies can combine with resource-based policies, while permission boundaries, session policies, and SCPs can restrict the result. Any explicit deny still overrides an allow.
What to Remember
In AWS, access is the result of evaluation, not the title of a policy document.
Questions to Check Understanding
What is the difference between implicit deny and explicit deny?
Why can multiple policies change the final result of one request?
What should a reviewer inspect when debugging unexpected access?
Further Study
Policy evaluation logic - Official AWS explanation of how authentication, request context, and policy types produce the final decision.
Policies and permissions in AWS Identity and Access Management - Official AWS reference for policy types and how they interact.