Why are cross-account users getting Access Denied errors when they try to access S3 objects encrypted by a custom AWS KMS key?

Last updated: 2021-03-11

My Amazon Simple Storage Service (Amazon S3) bucket is encrypted with a custom AWS Key Management Service (AWS KMS) key. When users from another AWS account try to access the objects in my bucket, they get an Access Denied error. How can I fix this?

Short description

To grant access to an AWS KMS-encrypted bucket in Account A to a user in Account B, you must have these permissions in place:

  • The bucket policy in Account A must grant access to Account B.
  • The AWS KMS key policy in Account A must grant access to the user in Account B.
  • The AWS Identity and Access Management (IAM) policy in Account B must grant the user access to both the bucket and key in Account A.

To troubleshoot the Access Denied error, verify that these permissions are set up correctly.

Resolution

The bucket policy in Account A must grant access to the user in Account B

From Account A, review the bucket policy and confirm that there is a statement that allows access from the account ID of Account B.

For example, this bucket policy allows s3:GetObject access to the account ID 111122223333:

{
  "Id": "ExamplePolicy1",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ExampleStmt1",
      "Action": [
        "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*",
      "Principal": {
        "AWS": [
          "111122223333"
        ]
      }
    }
  ]
}

The AWS KMS key policy in Account A must grant access to the user in Account B

The AWS KMS key policy must grant the user in Account B permissions to the kms:Decrypt action. For example, if you want to grant key access to only one IAM user or role, the key policy statement looks like this:

{
    "Sid": "Allow use of the key",
    "Effect": "Allow",
    "Principal": {
        "AWS": [
            "arn:aws:iam::111122223333:role/role_name"
        ]
    },
    "Action": [
        "kms:Decrypt"
    ],
    "Resource": "*"
}

From Account A, review the key policy using the AWS Management Console policy view. In the key policy, look for "Sid": "Allow use of the key". Then, confirm that the user in Account B is listed as a principal in that statement.

If you don't see the statement "Sid": "Allow use of the key", switch to view the key policy using the console default view. Then, add Account B's account ID as an external account with access to the key.

The IAM user policy in Account B must grant the user access to both the bucket and key in Account A

From Account B, open the IAM console, and then open the IAM user or role associated with the user in Account B. Review the list of permissions policies applied to IAM user or role. Then, verify that there are applied policies that grant access to both the bucket and key.

Note: If the IAM user or role in Account B already has administrator access, then you don't need to grant access to the key.

The following example policy grants the IAM user in Account B access to objects and KMS key (to decrypt objects in a bucket):

{
    "Version": "2012-10-17",
    "Statement": [{
            "Sid": "ExampleStmt1",
            "Action": [
                "s3:GetObject"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
        },
        {
            "Sid": "ExampleStmt2",
            "Action": [
                "kms:Decrypt"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:kms:bucket-region:444455556666:key/1234abcd-12ab-34cd-56ef-1234567890ab"
        }
    ]
}

For more information about how to add or correct the IAM user's permissions, see Changing permissions for an IAM user.


Did this article help?


Do you need billing or technical support?