AWS S3 bucket policies have a handy NotPrincipal
element that allows you restrict actions to specific principals. For example, the following allows you only allow deletes from two specified roles:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyObjectDeleteWithWhitelist",
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::123456789012:role/SuperRoleOne",
"arn:aws:iam::123456789012:role/SuperRoleTwo"
]
},
"Action": "s3:DeleteObject",
"Resource": "arn:aws:s3:::mybucket/*"
}
]
}
But what if you want to restrict it to an assumed role? While working on a Serverless Framework project, I wanted to open up a S3 bucket to allow deletes from a Lambda function (and only that Lambda function).
Surprisingly, the following S3 bucket policy didn’t work:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyObjectDeleteWithWhitelist",
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::123456789012:role/my-lambda-role"
]
},
"Action": "s3:DeleteObject",
"Resource": "arn:aws:s3:::mybucket/*"
}
]
}
With a bit of digging and troubleshooting, I realized that the Lambda function assumes the role you provide, and that assumed role must also be added to the S3 bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyObjectDeleteWithWhitelist",
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::123456789012:role/my-lambda-role",
"arn:aws:sts::123456789012:assumed-role/my-lambda-role/my-lambda-function"
]
},
"Action": "s3:DeleteObject",
"Resource": "arn:aws:s3:::mybucket/*"
}
]
}
This will prevent any entity from deleting from the S3 bucket except for your Lambda function.
If this isn’t your exact scenario, and/or you’re looking for more details, check out How to Restrict Amazon S3 Bucket Access to a Specific IAM Role by AWS.
Top comments (0)