DEV Community

Mark Tse
Mark Tse

Posted on • Originally published at blog.neverendingqs.com on

S3 Bucket Policy - NotPrincipal and Lambda Functions

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)