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-12-02

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

1.    Open the AWS KMS console, and then view the key's policy document using the policy view. Modify the key's policy to grant the IAM user permissions for the kms:GenerateDataKey and kms:Decrypt actions at minimum. You can add a statement that's similar to the following:

{
  "Sid": "ExampleStmt",
  "Action": [
    "kms:Decrypt",
    "kms:GenerateDataKey"
  ],
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::111122223333:user/Jane"
  },
  "Resource": "*"
}

Note: This example policy includes only the minimum permissions required for an individual IAM user to download and upload to an encrypted S3 bucket. You can modify or expand the permissions based on your use case.

2.    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": "ExampleStmt",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
    }
  ]
}

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

Important: You can grant cross-account access for a customer managed AWS KMS key, but not for an AWS managed AWS KMS key. The key policy of an AWS managed AWS KMS key can't be modified.

1.    Open the AWS KMS console, and then view the key's policy document using the policy view. Modify the key's policy to grant the IAM user permissions for the kms:GenerateDataKey and kms:Decrypt actions at minimum. You can add a statement that's similar to the following:

{
  "Sid": "ExampleStmt",
  "Action": [
    "kms:Decrypt",
    "kms:GenerateDataKey"
  ],
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::111122223333:user/Jane"
  },
  "Resource": "*"
}

Note: This example policy includes only the minimum permissions required for an individual IAM user to download and upload to an encrypted S3 bucket. You can modify or expand the permissions based on your use case.

2.    Open the IAM console from the account 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. 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:::DOC-EXAMPLE-BUCKET/*"
    },
    {
      "Sid": "ListBucket",
      "Action": [
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET"
    },
    {
      "Sid": "KMSAccess",
      "Action": [
        "kms:Decrypt",
        "kms:GenerateDataKey"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:kms:example-region-1:123456789098:key/111aa2bb-333c-4d44-5555-a111bb2c33dd"
    }
  ]
}

3.    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:::DOC-EXAMPLE-BUCKET/*",
      "Principal": {
        "AWS": [
          "arn:aws:iam::111122223333:user/Jane"
        ]
      }
    },
    {
      "Sid": "ListBucket",
      "Action": [
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET",
      "Principal": {
        "AWS": [
          "arn:aws:iam::111122223333:user/Jane"
        ]
      }
    }
  ]
}