Identity and permissions · Chapter 1 of 2
How AWS decides whether to allow a call
Every AccessDenied in AWS is the same algorithm returning a decision you did not expect. Once you can run that algorithm in your head, permission errors stop being mysterious.
FoundationsBuilds the idea from nothing. No prior AWS assumed.
Nothing is allowed until something allows it
A brand-new IAM user has no policies. What can they do?
A developer calls s3:GetObject. AWS starts from an implicit deny — nothing is permitted until some policy allows it.
- 01
Ordinary resource access starts denied
A new IAM identity cannot list your S3 buckets without a grant. Having credentials does not itself grant resource permissions. There are specific exceptions: STS GetCallerIdentity returns your account and caller identity without requiring an allow, even when that action has an explicit deny. Use the default-deny model for resource access, and check the API documentation for exceptions.
- 02
That base case has a name: implicit deny
When nothing in the account says yes, the answer is no. It is called *implicit* because no policy had to be written to produce it. Most permission errors a beginner hits are implicit denies: nobody blocked you, it is simply that nobody ever allowed you.
- 03
An allow has to come from a document you can point at
Permissions arrive from identity policies attached to a user, a group the user belongs to, or a role they assumed; and for a handful of services, from a resource policy attached to the thing being touched — a bucket policy, a queue policy, a KMS key policy. If you cannot point at the document that grants a call, the call is denied.
- 04
Which is why the first fix that works is usually the wrong one
AdministratorAccess supplies broad identity-based allows, so it can hide a missing permission. It does not bypass explicit denies, organization controls, permissions boundaries or service-specific access requirements. Grant the action the task requires and verify the resource scope instead of expanding access until the error disappears.
Check yourself
A user has no policies attached and belongs to no groups. They call s3:ListAllMyBuckets. What happens?
Under the hoodThe same thing from underneath: limits, failure modes, numbers.
The order the decision is made in
When several policies apply at once and they disagree, which one wins?
A developer calls s3:GetObject. AWS starts from an implicit deny — nothing is permitted until some policy allows it.
- 01
It is one algorithm, and it always runs in the same order
AWS collects every policy that could apply to the call — identity policies, resource policies, permissions boundaries, session policies, and any Service Control Policies from AWS Organizations — and evaluates them together. The result is a single decision, and the order that produces it never changes.
- 02
Step one: is there an explicit deny anywhere?
If any applicable policy contains a matching statement with `"Effect": "Deny"`, the call is denied and evaluation stops. Nothing overrides it. Not AdministratorAccess, not a resource policy, not being the account owner if a boundary or SCP is involved. This is why a deny statement is the strongest tool in IAM and why it should be used sparingly and precisely.
- 03
Step two: do the ceilings permit it?
SCPs and permissions boundaries are filters, not grants. A call has to be inside every applicable ceiling to survive. The critical property — and the one exam questions are built on — is that a ceiling can only ever reduce. Attaching a boundary that allows `s3:*` to a user with no policies grants that user nothing at all.
- 04
Step three: is there an explicit allow?
For the simplified identity-policy case taught here, the requested action and resource need an applicable allow within the relevant controls. Actual AWS evaluation also depends on the principal and policy type: direct resource-policy grants, role sessions, cross-account access and service-specific exceptions need their own rules. The local simulator covers a documented subset.
- 05
Why the order is deny-first and not allow-first
Because a security boundary that could be widened by adding another policy would not be a boundary. Deny-first means a control team can attach a deny to an Organizational Unit and be certain that no account administrator underneath can undo it by granting themselves more. The guarantee runs in exactly one direction, and that is what makes it worth anything.
The numbers
- Simplified identity-policy reasoning
- matching deny → applicable controls → matching allowResource-policy principal and service-specific rules can change the evaluation path; verify the official references below.
- Managed policies
- User: 10 default / 20 maximum; role: 20 / 25Groups: 10. Quotas are entity-specific; inline policies do not count against managed-policy attachment quotas.
- Aggregate inline policy size
- 2,048 chars (user), 10,240 (role)Group: 5,120. IAM excludes whitespace when calculating these limits.
- Permissions boundary per identity
- Exactly 1A ceiling, never a grant. Effective access is the intersection with the identity policy.
- Policy evaluation cost
- Free and not rate-limitedThere is no performance argument for a broader policy.
Check yourself
A user has AdministratorAccess attached. An SCP on their Organizational Unit denies s3:DeleteBucket. They call s3:DeleteBucket. What happens?
In practiceThe judgement call you actually have to make.
Users, groups, roles: picking the right one
You need to give something access. Which kind of identity do you reach for?
- 01
A role, unless the thing is a human without federation
Assuming a role returns temporary credentials. CLI AssumeRole sessions default to one hour; duration and service-managed sessions follow the applicable rules. Roles avoid distributing long-lived user access keys, but temporary credentials can still leak and remain usable until they expire or are revoked. EC2 instance profiles, Lambda execution roles and ECS task roles provide service-specific ways to supply permissions.
- 02
A group is a management tool, not a security boundary
Groups exist so that a permission lives in one place when five people need it. Nothing assumes a group and nothing is granted to a group as a principal — a group cannot appear in a resource policy. Put policies on the group, put people in the group, and the "why does this one engineer have S3 write" question stays answerable.
- 03
A user with long-lived access keys is a liability you are choosing to accept
Access keys do not expire, do not rotate themselves, and end up committed to repositories with reliable regularity. There are real cases for them — an on-premises server, a third-party tool that cannot federate — and in those cases the answer is a narrow policy, a rotation schedule, and an alarm. The answer is not "and also AdministratorAccess so it stops erroring".
Check yourself
An application on EC2 needs to read one S3 bucket. What should you attach?
Official references & further reading
These lessons simplify selected behaviors for learning. Verify current service limits, Region support and production requirements with the official references. Experiments describe their own assumptions.
Report an error or suggest a clearer explanation →