Reputation: 21
I originally setup SES to receive emails and during the process I created a bucket policy which allowed the service to put emails in S3. I now have a lambda function that should be able to use STS to assume a role and access the same bucket. Unfortunately, I can't figure out the right policy to allow both the service and the IAM Role to access the same bucket, right now I get 'access denied'. I used the policy simulator to verify that everything else functioned as it should e.g I added a generic policy with more actions on the aim Role and if I tell the simulator to ignore the bucket policy then it says it CAN access the files.
I've tried having two statements, one with the principal set to 'services' and the other to the aim roles (added two just to see if either would work)
{
"Version": "2012-10-17",
"Id": "Policy1478013193612",
"Statement": [
{
"Sid": "Stmt1478013187203",
"Effect": "Allow",
"Principal": {
"Service": "ses.amazonaws.com"
},
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::email-01-bucket/*"
},
{
"Sid": "Stmt55",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:sts::[id-num-with-no-dashes]:assumed-role/[role-name]/[session-name]",
"arn:aws:iam::[id-num-with-no-dashes]:role/[role-name]"
]
},
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::email-01-bucket/*"
}
]
}
I also tried putting it in 1 statement:
{
"Version": "2012-10-17",
"Id": "Policy1478013193612",
"Statement": [
{
"Sid": "Stmt1478013187203",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:sts::[id-num-with-no-dashes]:assumed-role/[role-name]/[session-name]",
"arn:aws:iam::[id-num-with-no-dashes]:role/[role-name]"
],
"Service": "ses.amazonaws.com"
},
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::email-01-bucket/*"
}
]
}
BTW, the file path is : arn:aws:s3:::email-01-bucket/email/[file-id]
I couldn't put ListBucket since it would throw an error.
Any help is appreciated :D
Let me know if I should add anything else
[Update]
In an effort to make finding the right policy easier I will describe what I currently have setup in the IAM policy simulator, I'm assuming if we can get it working here then it should work on a lambda function.
Role: serviceDev
This role has two policies attached to it.
1) serviceFS:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:PutBucketLogging",
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::email-01-bucket/*"
}
]
}
2) AWSLambdaBasicExecutionRole
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
In the Policy Simulator:
The dropdown Select Service
is set to S3
The dropdown Select Action
is set to GetObject
Under Resource
> Object
I type the path to an existing file arn:aws:s3:::email-01-bucket/email/u245hnt85uivpfkrrlhgo0jt86gfjgnca2fgocg1
(after double checking that the file is in fact there)
Once I do that there is now a Resource Policies
section on the left which shows me the Bucket policy attached to my bucket with the following policy:
{
"Version": "2012-10-17",
"Id": "Policy1478013193612",
"Statement": [
{
"Sid": "Stmt1478013187203",
"Effect": "Allow",
"Principal": {
"Service": "ses.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::email-01-bucket/*"
}
]
}
Now here is where I get lost, going back to the Resource
> Object
area where I specify the path to an existing file there is a checkbox labeled Include Resource Policy
, if I uncheck it then the Simulator says that the permission was allowed BUT if I check it then I get the following error:
The simulation could not be performed! : Simulation failed!
Upvotes: 0
Views: 1836
Reputation: 78563
As far as I understand your requirements, you need one S3 bucket policy (to allow SES to put objects into your S3 bucket) and you need one IAM role that your Lambda function will use to list that bucket and to put/get objets in that bucket. The IAM role also needs a trust relationship, allowing the AWS Lambda Service to assume the role on your behalf (so that you don't have to manually assume that role in your code).
Specifically:
S3 bucket policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSESPuts",
"Effect": "Allow",
"Principal": {
"Service": "ses.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::BUCKET-NAME/*",
"Condition": {
"StringEquals": {
"aws:Referer": "AWSACCOUNTID"
}
}
}
]
}
IAM role:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "sidlist",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::BUCKET-NAME"
},
{
"Sid": "sidputget",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::BUCKET-NAME/*"
}
]
}
Trust relationship on the IAM role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
I'm not sure why you included s3:PutBucketLogging in your example but if you genuinely need it then add it to the Lambda's IAM role against the arn:aws:s3:::BUCKET-NAME resource (not the arn:aws:s3:::BUCKET-NAME/* resource -- it's an action on buckets not on objects)
Upvotes: 2