My Amazon S3 bucket has default encryption using a custom AWS KMS key. How can I allow users to download from and upload to the bucket?

Last updated: 2020-03-27

I set up my Amazon Simple Storage Service (Amazon S3) bucket to use default encryption with a custom AWS Key Management Service (AWS KMS) key. I want an AWS Identity and Access Management (IAM) user to be able to download from and upload to the bucket. How can I do that?

Resolution

The IAM user and the AWS KMS key belong to the same AWS account

First, open the AWS KMS console and follow these steps:

  1. From the navigation pane, choose Customer managed keys.
  2. From the list of keys, open the key that's associated with your bucket.
  3. Under Key Users, choose Add.
  4. From the list of IAM users and roles, select the IAM user.
  5. Choose Add.

Then, open the IAM console. Add a policy to the IAM user that grants the permissions to upload and download from the bucket. You can use a policy that's similar to the following:

Note: For the Resource value, enter the Amazon Resource Name (ARN) for the bucket with a wildcard character to indicate the objects in the bucket.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ExampleStmt1",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::awsexamplebucket/*"
    }
  ]
}

Important: The S3 permissions granted by the IAM user policy can be blocked by an explicit deny statement in the bucket policy. Be sure to review the bucket policy to confirm that there aren't any explicit deny statements that conflict with the IAM user policy.

The IAM user is in a different account than the AWS KMS key and S3 bucket

First, open the AWS KMS console from the account that owns the AWS KMS key and S3 bucket. Follow these steps:

  1. From the navigation pane, choose Customer managed keys.
  2. From the list of keys, open the key that's associated with your bucket.
  3. Under Other AWS accounts, choose Add other AWS accounts.
  4. In the text box, enter the AWS account ID of the IAM user.
  5. Choose Save changes.

Then, open the IAM console from the account that that the IAM user belongs to. Add a policy to the IAM user that grants the permissions to upload and download from the bucket, as well as work with the AWS KMS key that's associated with the bucket.

For cross-account scenarios, consider granting s3:PutObjectAcl permissions so that the IAM user can upload an object and then grant the bucket's account full control of the object (bucket-owner-full-control). Additionally, consider granting s3:ListBucket permissions, which is required for running a sync operation, or a recursive copy operation. You can use a policy that's similar to the following:

Note: For the first Resource value, enter the ARN for the bucket with a wildcard character to indicate the objects in the bucket. For the second Resource value, enter the ARN for the bucket. For the third Resource value, enter the AWS KMS key's ARN.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DownloadandUpload",
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion",
        "s3:PutObject",
        "s3:PutObjectAcl"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::awsexamplebucket/*"
    },
    {
      "Sid": "ListBucket",
      "Action": [
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::awsexamplebucket"
    },
    {
      "Sid": "KMSAccess",
      "Action": [
        "kms:Decrypt",
        "kms:DescribeKey",
        "kms:Encrypt",
        "kms:GenerateDataKey*",
        "kms:ReEncrypt*"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:kms:example-region-1:123456789098:key/111aa2bb-333c-4d44-5555-a111bb2c33dd"
    }
  ]
}

Finally, open the Amazon S3 console from the account that owns the S3 bucket. Update the bucket policy to grant the IAM user access to the bucket. You can use a policy that's similar to the following:

Note: For the Principal values, enter the IAM user's ARN. For the first Resource value, enter the ARN for the bucket with a wildcard character to indicate the objects in the bucket. For the second Resource value, enter the ARN for the bucket.

{
  "Id": "Policy1584399307003",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DownloadandUpload",
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion",
        "s3:PutObject",
        "s3:PutObjectAcl"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::awsexamplebucket/*",
      "Principal": {
        "AWS": [
          "arn:aws:iam::123exampleaccountID:user/Jane"
        ]
      }
    },
    {
      "Sid": "ListBucket",
      "Action": [
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::awsexamplebucket",
      "Principal": {
        "AWS": [
          "arn:aws:iam::123exampleaccountID:user/Jane"
        ]
      }
    }
  ]
}