Related
Is it possible to create a trust that allow federated users from cognito to assume role according to a custom attribute?
For example with a tenant attribute:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "us-east-1:12345678-corner-cafe-123456790ab"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "unauthenticated"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:custom:tenant": "tenant-name"
}
}
}
]
}
I'm using get_credentials_for_identity api with cognito token to assume this role.
Yes, this is definitely possible with attributes for access control. This will only work for an authenticated user (you need an ID token to map claims to principal tags).
Your trust policy needs to looks like this:
{
"Statement": [
{
"Effect": "Allow",
"Action": [
"sts:AssumeRoleWithWebIdentity",
"sts:TagSession"
],
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "us-east-1:12345678-corner-cafe-123456790ab"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "authenticated"
}
},
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
}
}
]
}
The difference is the sts:TagSession action and the fact that amr must be authenticated.
Policy for assumed role will look something like this:
{
"PolicyDocument": {
"Statement": [
{
"Action": "s3:GetObject",
"Effect": "Allow",
"Resource": "arn:aws:s3:::your-bucket-name/cognito/attributes/by_family_name/${aws:PrincipalTag/family_name}/*"
},
{
"Action": "s3:GetObject",
"Condition": {
"StringEquals": {
"s3:ExistingObjectTag/given_name": "${aws:PrincipalTag/given_name}"
}
},
"Effect": "Allow",
"Resource": "arn:aws:s3:::your-bucket-name/cognito/attributes/by_tag/*"
}
],
"Version": "2012-10-17"
},
"PolicyName": "attributes-policy"
}
You need to configure your Cognito (or any other) provider in Identity Pool to do the mapping between claims from the token to tags. You can do it in console under Attributes for access control. Or with CLI like this:
aws cognito-identity set-principal-tag-attribute-map --cli-input-json file://set-principal-tag-attribute-map.json
Where set-principal-tag-attribute-map.json would look something like this (for Cognito as IDP):
{
"IdentityPoolId": "here-is-your-identity-pool-id",
"IdentityProviderName": "cognito-idp.<region>.amazonaws.com/<user_pool_id>",
"UseDefaults": false,
"PrincipalTags": {
"given_name": "given_name",
"family_name": "family_name"
}
}
You can find more details in documentation here: https://docs.aws.amazon.com/cognito/latest/developerguide/attributes-for-access-control.html
I used this policy on AWS to try connecting AoC with an S3 bucket:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::880559705280:role/atp-aws-us-east-1-ts-atc-node"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringLike": {
"sts:ExternalId": "crn:v1:bluemix:public:aspservice-service:global:a/2dd2425e9a424641a12855a1fd5e85ee:70740386-6ca4-4473-bf9b-69a1fd22be12:::c1893698-abfa-4934-a7ca-1a6d837df5e0"
}
}
}
]
}
but when copied on Bucket Policy, I receive Error: Statement is missing required element.
What is wrong?
You need to paste this policy file into Trust relationship policy in Role tab.
I'm looking to grant access to a bucket that will allow instances in my VPC full access to it along with machines via our Data Center. Without the aws:SouceIp line, I can restrict access to VPC online machines.
I need the policy to work so that the bucket can only be accessible from machines within the VPC AND from my office.
{
"Version": "2012-10-17",
"Id": "Policy1496253408968",
"Statement": [
{
"Sid": "Stmt1496253402061",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::xyz-sam-test/*",
"arn:aws:s3:::xyz-sam-test"
],
"Condition": {
"StringLike": {
"aws:sourceVpc": "vpc-dcb634bf",
"aws:SourceIp": "<MY PUBLIC IP>"
}
}
}
]
}
You can generate a policy whose Effect is to Deny access to the bucket when StringNotLike Condition for both keys matches those specific wildcards.
{
"Version": "2012-10-17",
"Id": "Policy1496253408968",
"Statement": [
{
"Sid": "Stmt1496253402061",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::xyz-sam-test/*",
"arn:aws:s3:::xyz-sam-test"
],
"Condition": {
"StringNotLike": {
"aws:sourceVpc": "vpc-dcb634bf",
"aws:SourceIp": "<MY PUBLIC IP>"
}
}
}
]
}
The second condition could also be separated to its own statement. AWS applies a logical OR across the statements. 1
{
"Version": "2012-10-17",
"Id": "Policy1496253408968",
"Statement": [
{
"Sid": "Stmt1496253402061",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::xyz-sam-test/*",
"arn:aws:s3:::xyz-sam-test"
],
"Condition": {
"StringLike": {
"aws:sourceVpc": "vpc-dcb634bf",
}
}
},
{
"Sid": "Stmt1496253402062",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::xyz-sam-test/*",
"arn:aws:s3:::xyz-sam-test"
],
"Condition": {
"StringLike": {
"aws:SourceIp": "<MY PUBLIC IP>"
}
}
}
]
}
AWS has predefined condition operators and keys (like aws:CurrentTime). Individual AWS services also define service-specific keys.
As an example, assume that you want to let user John access your Amazon SQS queue under the following conditions:
The time is after 12:00 p.m. on 7/16/2019
The time is before 3:00 p.m. on 7/16/2019
The request comes from an IP address within the range 192.0.2.0 to 192.0.2.255 or 203.0.113.0 to 203.0.113.255.
Your condition block has three separate condition operators, and all three of them must be met for John to have access to your queue, topic, or resource.
The following shows what the condition block looks like in your policy. The two values for aws:SourceIp are evaluated using OR. The three separate condition operators are evaluated using AND.
"Condition" : {
"DateGreaterThan" : {
"aws:CurrentTime" : "2019-07-16T12:00:00Z"
},
"DateLessThan": {
"aws:CurrentTime" : "2019-07-16T15:00:00Z"
},
"IpAddress" : {
"aws:SourceIp" : ["192.0.2.0/24", "203.0.113.0/24"]
}
}
reference: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_multi-value-conditions.html
this is an old question, but I think that there is a better solution with AWS new capabilities. Especially, I don't really like the deny / StringNotLike combination, because denying on an s3 policy can have unexpected effects such as locking your own S3 bucket down, by denying yourself (this could only be fixed by using the root account, which you may not have easily accessible in a professional context)
So the solution I have in mind is to use ForAnyValue in your condition (source). e.g something like this:
{
"Version": "2012-10-17",
"Id": "Policy1496253408968",
"Statement": [
{
"Sid": "Stmt1496253402061",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::xyz-sam-test/*",
"arn:aws:s3:::xyz-sam-test"
],
"Condition": {
"ForAnyValue:StringEquals": {
"aws:sourceVpc": [
"vpc-dcb634bf",
"<MY PUBLIC IP>"
]
}
}
}
]
}
I am trying to create an event on an S3 bucket (named testBucket) so that every time a new object is created, a message is sent to SNS.
I've done some research and added:
"ArnLike": {"aws:SourceArn": "arn:aws:s3:*:*:testBucket"}
to the target topic's policy.
But, when I try to create the event, it still shows: Permissions on the destination topic do not allow S3 to publish notifications from this bucket.
Any ideas?
Problem solved. Before I was adding the condition line inside the default statement:
"ArnLike": {
"aws:SourceArn": "arn:aws:s3:*:*:testBucket"
}
Turns out I have to create a new statement with publish action in it.
{
"Sid": "publish-from-s3",
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": "SNS:Publish",
"Resource": "arn:aws:sns:ap-southeast-2:XXXXXXXXXXXXXX:testTopicforS3",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:s3:*:*:testBucket"
}
}
}
Yeah, after create SNS, modify it to add a statement (after the default one):
{
"Statement": [
{
"Sid": "__default_statement_ID",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"SNS:Publish",
"SNS:RemovePermission",
"SNS:SetTopicAttributes",
"SNS:DeleteTopic",
"SNS:ListSubscriptionsByTopic",
"SNS:GetTopicAttributes",
"SNS:Receive",
"SNS:AddPermission",
"SNS:Subscribe"
],
"Resource": "your sns arn"
},
{
"Sid": "s3",
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": "SNS:Publish",
"Resource": "your sns arn"
}
]
}
Instead of adding a new statement, put "Service": "s3.awsamazon.com" inside Principal.
So it would look like:
Statement: [
{
"Sid": "publish-from-s3",
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com", # ADD THIS!
"AWS": <AWS_Account_Name_for_Access>
},
"Action": "SNS:Publish",
"Resource": "arn:aws:sns:ap-southeast-2:XXXXXXXXXXXXXX:testTopicforS3",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:s3:*:*:*"
}
}
}
]
I believe you need to allow the S3 bucket owner to publish to your topic. I usually first test the functionality by allowing everyone to publish to the topic then add more selective policy details later.
If you select your SNS topic in the AWS console, then choose Other topic actions, and select Edit Topic policy, then you'll see the Basic View tab. Under the section "Allow these users to publish messages to this topic", select Everyone and save. Next add the event to S3 and verify the basic event publishing works. Then you can lock down detailed policy changes later using the Advanced View.
"Principal":
{
"Service": "s3.amazonaws.com"
}
&
"ArnLike":
{
"aws:SourceArn": "arn:aws:s3:*:*:Bucket_name"
}
is important.
If you want to have any bucket in an account be able to publish or subscribe to the topic (yes this is a more generalized solution and therefore less secure but if you're running into circular dependency issues with trying to allow a bucket to be able to publish to the topic and add a subscription from the bucket to the topic, this will help):
{
"Id": "your-topic-policy-id",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "statement-id",
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": ["sns:Publish", "sns:Subscribe"],
"Resource": "your-sns-topic-arn",
"Condition": {
"StringEquals": {
"AWS:SourceAccount": "account-id"
}
}
}
]
}
I'm trying to make my entire S3 bucket public, but when I try to add the policy:
{
"Id": "Policy1454540872039",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1454540868094",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::sneakysnap/*",
"Principal": {
"AWS": [
"985506495298"
]
}
}
]
}
It tells me that my "Resource is invalid", but that is definitely the right arn and that is definitely the right bucket name. Anyone know what's going on?
I had this "problem" when I was trying to set a policy on the wrong bucket. That is, my arn in the policy was reading arn:aws:s3:::my-bucket-A/* but I was attempting to set it on my-bucket-B
I had solved the problem by this
arn:aws:s3:::your-bucket-name-here/*
'
If you are creating a policy for an access point it appears that aws will only accept the following format:
i) account id and region must be specified; and
ii) the literal string object must be included (object is not my bucket name)
arn:aws:s3:region:accountid:accesspoint/myaccesspointname/object/*
I found this answer here -> https://forums.aws.amazon.com/thread.jspa?threadID=315596
I faced the same issue and the following could fix your error. I hope this helps anyone facing the same. You need to specify the account ID that corresponds to the region for your load balancer and bucket.
"Principal": {
"AWS": [
"*********"
Please refer to this & update accordingly. This would solve this issue.
See also the Bucket Permissions section of Access Logs for Your Application Load Balancer.
I also had the same problem!
I was using wrong bucket name so I correct it.
It worked for me!
Best of Luck !
I was getting this error as well. The following change fixed it... No idea why.
This bucket threw the error: bleeblahblo-stuff
This worked: bleeblahblostuff
Maybe it was the dash.... Maybe the bucket length... Or maybe a combination of the two?? Both buckets had the same settings. Hmmm.
I was facing the same problem. I was was not using the correct resource name.
I did change the resource name to exactly of that bucket for which I was creating the bucket policy e.g
"Resource": "arn:aws:s3:::abc/*"
to
"Resource": "arn:aws:s3:::abc12/*"
My problem was that when I created my S3 bucket, by default the following were true:
Manage public access control lists (ACLs)
Block new public ACLs and uploading public objects (Recommended)
True
Remove public access granted through public ACLs (Recommended)
True
Manage public bucket policies
Block new public bucket policies (Recommended)
True
Block public and cross-account access if bucket has public policies (Recommended)
True
I had to set these all to false in order for me to change my bucket policy.
If you're trying the AWS startup workshop, try to close the website-bucket-policy.json file, an re-open it. It works for me, and I guess the update of the json file is not saved automatically unless you close it.
See if the bucket name you are specifying in Resource exists or not. The above answer from Vitaly solved my issue.
the problem I realized I had was that my bucket had a ".com" extension which needs to be included in your arn
To add to iamsohel's answer. I had this same issue when trying to set an S3 policy for enabling Elastic load balancer access logs using Terraform.
Here's the policy I was trying to set:
Access logs for your Application Load Balancer
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::elb-account-id:root"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::bucket-name/prefix/AWSLogs/your-aws-account-id/*"
},
{
"Effect": "Allow",
"Principal": {
"Service": "delivery.logs.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::bucket-name/prefix/AWSLogs/your-aws-account-id/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
},
{
"Effect": "Allow",
"Principal": {
"Service": "delivery.logs.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::bucket-name"
}
]
}
But I wanted to add some variables to the policy. My initial policy looked like this:
bucket_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::${var.bucket_name.2}"
},
{
"Effect": "Allow",
"Principal": {
"Service": "delivery.logs.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::${var.bucket_name.2}",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
},
{
"Effect": "Allow",
"Principal": {
"Service": "delivery.logs.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::${var.bucket_name.2}"
}
]
}
EOF
But this was throwing an error:
Error: Error putting S3 policy: MalformedPolicy: Policy has invalid resource
│ status code: 400, request id: 3HHH9QK9SKB1V9Z0, host id: 8mOrnGi/nsHIcz59kryeriVExU7v+XgGpTw64GHfhjgkwhA3WKSfG7eNbgkMgBMA8qYlyUTLYP8=
│
│ with module.s3_bucket_policy_1.aws_s3_bucket_policy.main,
│ on ../../../../modules/aws/s3-bucket-policy/main.tf line 1, in resource "aws_s3_bucket_policy" "main":
│ 1: resource "aws_s3_bucket_policy" "main" {
All I had to do was to add /* to the end of the arn for the bucket resource:
bucket_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::${var.bucket_name.2}/*"
},
{
"Effect": "Allow",
"Principal": {
"Service": "delivery.logs.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::${var.bucket_name.2}/*",
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
},
{
"Effect": "Allow",
"Principal": {
"Service": "delivery.logs.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::${var.bucket_name.2}"
}
]
}
EOF
In my case it was the missing region in the arn for govcloud - so the resource had to be
"arn:aws-us-gov:s3:::grcsimpletest"
rather than
"arn:aws:s3:::grcsimpletest"
Strangely the policy that failed was from an AWS doc.... That said, it kind of clicked when I edited the policy in the S3 console and it showed the bucket arm on the edit screen.