How do I troubleshoot explicit deny error messages when requesting API calls using IAM roles or users?

Last updated: 2022-05-31

I received an explicit deny error message when requesting an API call using an AWS Identity and Access Management (IAM) role or user. How can I troubleshoot and resolve explicit deny error messages?

Short description

In order for an IAM entity (role or user) to make a successful API call, the entity must meet the following conditions:

  • The role or user has the correct permissions to request an API call.
  • The permission isn't denied by any statement in all policies that are applicable to the request context.

If your IAM entity doesn't meet these conditions, then the API call fails and throws an (AccessDenied) error similar to this:

  • IAM user or role experiencing the issue: arn:XXXXXXXX:iam::XXXXXXXX:role/TestReadOnly

    Error: An error occurred (AccessDenied) when calling the RunInstances operation: User: arn:aws:iam::XXXXXXXX:user/tester is not authorized to perform: ec2:RunInstances on resource: role TestReadOnly with an explicit deny

Note: The troubleshooting steps in this article deal specifically with explicit deny errors and not implicit deny errors. For more information on implicit deny errors, see The difference between implicit and explicit denies.

Resolution

Explicit deny errors occur because of issues in one or more of the following policies:

  • Identity-based policies
  • Resource-based policies
  • Permissions boundary
  • Service control policies
  • Session policy

Identity-based policies

The identity-based policy controls the allowed/denied action of an entity. Use these troubleshooting steps to identify issues with identity-based policies.

Note: It's a best practice to use Deny with StringNotLike in conditions to prevent accidental privileged access.

1.    Check that there is no deny statement in your identity-based policy. This example contains a deny statement:

{
  "Effect": "Deny",
  "Action": "iam:DeleteRole"
  "Resource": "*"
}

2.    Check if Multi-Factor Authentication (MFA) is enforced on your policy. If your IAM entity authenticates without using another authentication factor when MFA is enforced, then the permission is denied. For example, if your entity authenticates using the AWS CLI without MFA, then your API call is denied. See this example of MFA enforcing:

{
  "Sid": "DenyAllExceptListedIfNoMFA",
  "Effect": "Deny",
  "NotAction": [
    "iam:CreateVirtualMFADevice",
    "iam:EnableMFADevice",
    "iam:GetUser",
    "iam:ListMFADevices",
    "iam:ListVirtualMFADevices",
    "iam:ResyncMFADevice",
    "sts:GetSessionToken"
  ],
  "Resource": "*",
  "Condition": {
    "BoolIfExists": {"aws:MultiFactorAuthPresent": "false"}
  }
}

This policy explicitly denies all API calls, except the ones that are mentioned in the NotAction policy element.

3.    Make sure that your policy meets all of the required conditions. If your policy has multiple condition operators or multiple keys, then the conditions are evaluated using AND logic. Each RequestTag key must be used in separate statements to get the same AND logic. This is an example of a common issue that causes the API call to fail:

{
  "Sid": "AllowRunInstancesWithRestrictions2",
  "Effect": "Deny",
  "Action": [
    "ec2:CreateVolume",
    "ec2:RunInstances"
  ],
  "Resource": [
    "arn:aws:ec2:*:*:volume/*",
    "arn:aws:ec2:*:*:instance/*"
  ],
  "Condition": {
    "ForAllValues:StringNotLike": {
      "aws:TagKeys": "Production"
    },
    "StringEquals": {
      "ec2:InstanceType": "t2.micro"
    }
  }
}

To avoid an explicit deny access error for these API calls, make sure that the preceding condition is fulfilled.

Note: The aws:TagKeys condition is case sensitive.

Resource-based policies

The resource-based policy allows or denies access to a resource. Unlike IAM identity-based policies which are unified, resource-based policies are designed by services. The following troubleshooting steps use Amazon Simple Storage Service (Amazon S3) resource-based policies and a VPC endpoint policy as examples.

S3 bucket policy evaluation

Amazon S3 Bucket policy evaluation works as follows:

Note: This assumes that the bucket ACL is set as default.

  • To access a bucket in the same account, an IAM entity needs permissions in the IAM identity-based the OR bucket policy.
  • To access a bucket in a different account, an IAM entity needs permissions in the bucket policy AND the IAM identity-based to gain access.

1.    Check for deny statements in the resource-based policy. This example shows a deny statement in the bucket policy:

{
  "Effect": "deny",
  "Principal": {
    "AWS": "arn:aws:iam::111111111111:role/ROLENAME"
  },
  "Action": "s3:ListBucket",
  "Resource": "arn:aws:s3:::MyExampleBucket"
}

2.    Check that the ARNs described in your policy are correct.

3.    The bucket policy denies access if the aws:userid of the current user does not equal what is defined in the policy. See this example:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::MyExampleBucket",
        "arn:aws:s3:::MyExampleBucket/*"
      ],
      "Condition": {
        "StringNotLike": {
          "aws:userId": [
            "AROAEXAMPLEID:*",
            "AIDAEXAMPLEID",
            "111111111111"
          ]
        }
      }
    }
  ]
}

VPC endpoint

A VPC endpoint policy is an IAM resource policy that is attached to an endpoint. This policy doesn't override or replace the IAM user policies or service-specific policies (such as S3 bucket policies).

There are two ways to control access to your Amazon S3 data when using an interface endpoint to connect to Amazon S3, :

  • You can control the AWS principals (AWS accounts, IAM users, and IAM roles) that can use the VPC endpoint to access the endpoint service.
  • You can control the VPCs or VPC endpoints that have access to your buckets by using Amazon S3 bucket policies.

This example below is an Amazon S3 bucket policy. The policy restricts access to a specific bucket, called examplebucket, from the VPC endpoint with the ID vpce-11111. The policy denies all access to the bucket if the specified endpoint isn't used. The aws:SourceVpce condition is used to specify the endpoint.

{
   "Version": "2012-10-17",
   "Id": "Policy123456789”,
   "Statement": [
     {
       "Sid": "AccessSpecificVPCEOnly",
       "Principal": "*",
       "Action": "s3:*",
       "Effect": "Deny",
       "Resource": ["arn:aws:s3:::examplebucket",
                    "arn:aws:s3:::examplebucket/*"],
       "Condition": {
         "StringNotEqualsIfExists": {
           "aws:SourceVpce": "vpce-11111”
         }
       }
     }
   ]
}

Always check that the VPC endpoint isn't explicitly denying access to the resource.

Permissions boundary

The permissions boundary is a managed policy that sets the maximum permissions that an identity-based policy can grant to an IAM entity. This managed policy can restrict permissions to entities, which might result in explicit deny error messages.

This example shows an action that is allowed in the IAM policy but is explicitly denied in the permissions boundary. See the permissions boundary below:

{
  "Version": "2012-10-17",

  "Statement": [

    {
      "Effect": "Deny",
      "Action": "ec2:*"

      "Resource": "*"
    }
  ]
}

The user has the following permissions:

{
  "Version": "2012-10-17",
  
  "Statement": {
    "Effect": "Allow",
    "Action": "ec2:RunInstances",
    
    "Resource": "*"
  }
}

Although the user has the RunInstances permission, they receive an explicit deny message when they request it. To resolve this error, make sure that your permissions boundary and IAM are both explicitly allowing this action.

Service control policies

A service control policy (SCP) allows you to manage permissions in your organization. The following example shows a deny statement in the SCP. In this example, the SCP is attached to a member account or to a particular Organization Unit (OU). It explicitly denies access to the RunInstances action:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": "ec2:RunInstances"

      "Resource": "*"
    }
  ]
}

To resolve explicit deny errors, take one of these actions:

  • Detach the SCP from the account.
  • Modify the deny statement by adding a condition that excludes some use case. For example, this SCP in this example does NOT deny ec2:RunInstances if the IAM principal uses the role CloudOps:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": "ec2:RunInstances"     
      "Resource": "*",
      "Condition": {
        "ArnNotLike": {
          "aws:PrincipalARN": "arn:aws:iam::*:role/CloudOps"
        }
      }
    }
  ]
}

Session policies

Session policies are advanced policies that you pass as a parameter when you programmatically create a temporary session for a role or user. You can create a role session, and pass session policies by using the AssumeRole, AssumeRoleWithSAML, or AssumeRoleWithWebIdentity API operations.

For example this policy generates the explicit deny error when the user tries to make a RunInstances API call. Always check for deny statements in the session policy:

{
  "Version": "2012-10-17",
  
  "Statement": {
    "Effect": "Deny",
    "Action": "ec2:RunInstances",
    
    "Resource": "*"
  }
}