Solving AWS Access Denied: The Comprehensive Guide (2025)
An advanced troubleshooting guide for diagnosing and fixing complex AWS Access Denied errors. Covers IAM policies, SCPs, permissions boundaries, VPC endpoints, and session policies.
What You'll Learn
💡 From Frustration to Fix
`AccessDenied` is the most common error in AWS, but its causes can be complex and hidden. This guide provides a systematic, layer-by-layer playbook to diagnose *any* permissions issue, turning frustrating guesswork into a predictable debugging process.
The IAM Decision Logic: How AWS Evaluates Policies
To solve `AccessDenied` errors, you must understand how AWS makes a permission decision. It's a multi-step process where an explicit `Deny` always wins.
- Explicit Deny: AWS first checks all applicable policies (Identity, Resource, SCPs, etc.) for an explicit `Deny` statement. If one is found, access is immediately denied.
- Explicit Allow: If there are no `Deny` statements, AWS looks for an `Allow` statement in any applicable policy.
- Implicit Deny: If no `Allow` statement is found, access is denied by default.
The "applicable policies" can include up to five different types, which we'll investigate next.
Step 1: Decode the Authorization Failure Message
Your first step should always be AWS CloudTrail. Often, `AccessDenied` errors contain an encoded message that tells you exactly why the request failed. You can decode it with the AWS CLI.
Terminal: Decode CLI Command
# 1. Find the event in CloudTrail and copy the encoded "authorizationFailure" message.
# 2. Run the decode command:
aws sts decode-authorization-message --encoded-message "ENCODED_MESSAGE_HERE"The output is a JSON object that often reveals the specific policy (`Deny` in an SCP, missing permission in a resource policy, etc.) that caused the failure.
Step 2: Troubleshoot the 5 Layers of AWS Permissions
If decoding the message isn't enough, you must systematically check the five policy types that can affect a request.
Layer 1: Identity-Based Policies
These are policies attached to your IAM user, group, or role. This is the most common place to look. Check: Does the IAM identity have an `Allow` for the action? Is there an explicit `Deny`?
Layer 2: Resource-Based Policies
These policies are attached directly to resources like S3 buckets, SQS queues, or KMS keys. Check: If you're accessing a resource in another account, does its resource policy trust your identity's account or role?
Layer 3: IAM Permissions Boundaries
A permissions boundary sets the *maximum* permissions an identity can have. Even if a user has `AdministratorAccess`, a permissions boundary can prevent them from creating certain resources. Check: Is there a permissions boundary on the IAM role/user that restricts the required action?
Layer 4: Service Control Policies (SCPs)
SCPs are organizational guardrails applied at the AWS Organization level. They can block actions for *all* principals in an account, including the root user. Check: Is there an SCP attached to your account's OU that explicitly denies the service or action?
Layer 5: Session Policies
When you assume a role programmatically, you can pass a session policy that further restricts the session's permissions. Check: If you are using an assumed role, was a restrictive session policy passed as part of the `AssumeRole` API call?
Common Scenarios & Gotchas
Cross-Account Role Access
Requires a "double allow." The user's IAM policy must `Allow` `sts:AssumeRole` on the target role, AND the target role's Trust Policy must `Allow` the user's account/role to assume it.
S3 Access via VPC Endpoint
A VPC Endpoint Policy acts as an additional gatekeeper. Even if your IAM and Bucket policies are correct, a restrictive Endpoint Policy can deny access to S3 from within a VPC.
KMS Encryption/Decryption
KMS requires two-sided permissions. The user needs IAM permissions for KMS actions (`kms:Decrypt`), AND the KMS Key Policy must grant those permissions to the user.