Reputation: 11
created 2 new kms key:
custom-client-side-encrypt-kms-key. (encrypt file on client side);
custom-server-side-encrypt-kms-key. (enable S3 server side encryption)
created new user:
test-user-encrypt
gave the user access to key and bucket; set up new key policy to allow user to use the key
aws s3api put-object --body newFile --bucket <bucket-name> --key inbound/newFile --server-side-encryption aws:kms --ssekms-key-id newKeyId
error: when calling the PutObject operation: Access Denied
aws s3api put-object --body newFile --bucket <bucket-name> --key inbound/newFile --server-side-encryption aws:kms
it works, but the object was encrypted with AWS managed default kms key
based on the above test, it seems the user has correct permissions to S3, but kms key permission was not correct.
here is my policies in brief:
key policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxid:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxxxid:user/test_user_encrypt"
},
"Action": [
"kms:ReEncrypt",
"kms:GenerateDataKey",
"kms:Encrypt",
"kms:DescribeKey",
"kms:Decrypt"
],
"Resource": "*",
"Condition": {
"ForAnyValue:IpAddress": {
"aws:SourceIp": [
"xx.xx.xx.xx",(IP addresses allowed)
"xx.xx.xx.xx",
]
}
}
},
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxxid:user/test_user_encrypt"
},
"Action": [
"kms:RevokeGrant",
"kms:ListGrants",
"kms:CreateGrant"
],
"Resource": "*",
"Condition": {
"Bool": {
"kms:GrantIsForAWSResource": "true"
}
}
"Condition": {
"ForAnyValue:IpAddress": {
"aws:SourceIp": [
"xx.xx.xx.xx", (IP addresses allowed)
"xx.xx.xx.xx",
]
}
}
}
]
}
IAM user policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": [
"kms:ReEncrypt",
"kms:GenerateDataKey",
"kms:Encrypt",
"kms:DescribeKey",
"kms:Decrypt"
],
"Resource": "arn:aws:kms:<region>:xxID:key/custom-client-side-encrypt-kms-key-id",
"Condition": {
"ForAnyValue:IpAddress": {
"aws:SourceIp": [
"xx.xx.xx.xx" (IP address allowed)
]
}
}
},
{
"Sid": "",
"Effect": "Allow",
"Action": [
"kms:RevokeGrant",
"kms:ReEncrypt",
"kms:ListGrants",
"kms:GenerateDataKey",
"kms:Encrypt",
"kms:DescribeKey",
"kms:Decrypt",
"kms:CreateGrant"
],
"Resource": "arn:aws:kms:<region>:xxxID:key/<custom-server-side-encrypt-key-id>"
"Condition": {
"ForAnyValue:IpAddress": {
"aws:SourceIp": [
"xx.xx.xx.xx", (IP address allowed)
]
}
}
},
{
"Sid": "",
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::bucket/inbound/*",
"Condition": {
"ForAnyValue:IpAddress": {
"aws:SourceIp": [
"xx.xxx.xxx.xx", (IP address allowed)
]
}
}
},
{
"Sid": "",
"Effect": "Deny",
"Action": [
"s3:PutObjectAcl",
"s3:PutObject",
"s3:ListMultipartUploadParts"
],
"Resource": [
"arn:aws:s3:::bucket/*/*/*",
"arn:aws:s3:::bucket/*/*/",
"arn:aws:s3:::bucket/*/"
]
}
]
}
bucket policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxid:user/test_user_encrypt"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::bucket/inbound/*",
"Condition": {
"ForAnyValue:IpAddress": {
"aws:SourceIp": [
"xx.xx.xx.xx", (IP address allowed)
]
}
}
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::xxxid:user/test_user_encrypt"
},
"Action": "s3:ListMultipartUploadParts",
"Resource": "arn:aws:s3:::bucket/inbound/*",
"Condition": {
"ForAnyValue:IpAddress": {
"aws:SourceIp": [
"xx.xx.xx.xx", (IP address allowed)
]
}
}
},
{
"Sid": "DenyIncorrectEncryptKey",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::bucket/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption-aws-kms-key-id": "arn:aws:kms:region:xxxid:key/custom-server-side-encrypt-kms-key-id"
}
}
},
{
"Sid": "DenyUnEncryptedObjectUploads",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::bucket/*",
"Condition": {
"StringNotEquals": {
"s3:x-amz-server-side-encryption": "aws:kms"
}
}
},
{
"Sid": "AllowSSLRequestsOnly",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::bucket/*",
"arn:aws:s3:::bucket"
],
"Condition": {
"Bool": {
"aws:SecureTransport": "false"
}
}
}
]
}
Upvotes: 1
Views: 1429
Reputation: 11
I figured out. I should NOT put condition "ip range" around kms:grant permissions.
"Condition": {
"ForAnyValue:IpAddress": {
"aws:SourceIp": [
"xx.xx.xx.xx", (IP address allowed)
]
}
}
that condition make kms:grant invalid. my guess....
after removed the condition, it works fine.
Upvotes: 0