Access S3 bucket after logging on Cognito from other account - amazon-web-services

I have two AWS accounts. The account A has a Cognito identity pool configured with roles for Authenticated and Unauthenticated.
The trusted relationship policy for Authenticated role looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "<identity_pool_id>"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "authenticated"
}
}
}
]
}
There is also a policy for Authenticated role that looks like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::users-pictures/public/*",
"arn:aws:s3:::users-pictures/protected/${cognito-identity.amazonaws.com:sub}/*",
"arn:aws:s3:::users-pictures/private/${cognito-identity.amazonaws.com:sub}/*"
],
"Effect": "Allow"
},
{
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::users-pictures/uploads/*"
],
"Effect": "Allow"
},
{
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::users-pictures/protected/*"
],
"Effect": "Allow"
},
{
"Condition": {
"StringLike": {
"s3:prefix": [
"public/",
"public/*",
"protected/",
"protected/*",
"private/${cognito-identity.amazonaws.com:sub}/",
"private/${cognito-identity.amazonaws.com:sub}/*"
]
}
},
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::users-pictures"
],
"Effect": "Allow"
}
]
}
On account B I have an application that must authenticate on Cognito from account A, but needs to access a bucket on account B.
This application uses Storage from Amplify.
The bucket structure must be something like this:
users-pictures/private/${cognito-identity.amazonaws.com:sub}/*
When Amplify authenticates on account A and tries to access this bucket on account B, it gets an Access Denied (403).
Probably it's missing some configuration on account A and/or account B.
Could you help me, please?

Related

AWS IAM Users, Groups & Policies

I have only 1 bucket called "partners" & then I am creating folders under it for each of our partners. Then I create an IAM user for each partner and the goal is to give them access to their individual folder. So, if I have two partners/users called Alice & Bob, I want to give each of them access to their individual folders called Alice & Bob under the "partners" bucket. The goal is not to give S3 Console access, just programmatically they should be able to read/write/modify their content in those folders.
So, I was thinking of simply creating "inline policy" for each IAM user to restrict them to their folder. Is this the correct way or are there other alternatives? Here is my current "inline policy" for IAM user Alice.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowListBucketIfSpecificPrefixIsIncludedInRequest",
"Action": [
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::partners"
],
"Condition": {
"StringLike": {
"s3:prefix": [
"alice/*"
]
}
}
},
{
"Sid": "AllowUserToReadWriteObjectDataInProperFolder",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::partners/alice/*"
]
},
{
"Sid": "ExplicitlyDenyAnyRequestsForAllOtherFolders",
"Action": [
"s3:ListBucket"
],
"Effect": "Deny",
"Resource": [
"arn:aws:s3:::partners"
],
"Condition": {
"StringNotLike": {
"s3:prefix": [
"alice/*",
""
]
},
"Null": {
"s3:prefix": false
}
}
}
]
}

AWS Cognito User Cannot Invoke Lambda (403 Not Authorized)

I’ve created a set of AWS Lambdas using the Serverless framework, and a React app which calls these. A user pool and an identity pool have been setup in AWS Cognito, and a table in DynamoDB. (I've followed the tutorial on serverless-stack.com). It's a simple notes app.
The client app is deployed to: https://dev.cakebook.co
The API is deployed: https://api.cakebook.co/dev/orders
However, after I log in using this Cognito user:
admin#example.com
Passw0rd!
I get a 403 response for the GET of the orders:
message: “User: arn:aws:sts::********8766:assumed-role/cakebook-api-dev-CognitoAuthRole-1DTRT5XGEGRXW/CognitoIdentityCredentials is not authorized to perform: execute-api:Invoke on resource: arn:aws:execute-api:us-east-2:********8766:sss6l7svxc/dev/GET/orders”
I'm new to all this, but it looks like my Cognito user does not have permission to call the Lambda (or API gateway?). Is that the issue? If so, how do I give the users permission to call the Lambdas?
UPDATE, requested JSON
Execution Role:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"logs:CreateLogStream"
],
"Resource": [
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-create:*",
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-get:*",
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-list:*",
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-update:*",
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-delete:*"
],
"Effect": "Allow"
},
{
"Action": [
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-create:*:*",
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-get:*:*",
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-list:*:*",
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-update:*:*",
"arn:aws:logs:us-east-2:********8766:log-group:/aws/lambda/cakebook-api-dev-delete:*:*"
],
"Effect": "Allow"
},
{
"Action": [
"dynamodb:DescribeTable",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem"
],
"Resource": [
"arn:aws:dynamodb:us-east-2:********8766:table/orders"
],
"Effect": "Allow"
},
{
"Sid": "1",
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-2:********8766:function:cakebook-api-dev-list",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:cognito-identity:us-east-2:********8766:identitypool/us-east-2:d9e4e505-c64a-4836-8e56-3af843dbe453"
}
}
}
]
}
Function Policy:
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "cakebook-api-dev-ListLambdaPermissionApiGateway-U7OCBI3JM44G",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-2:********8766:function:cakebook-api-dev-list",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:execute-api:us-east-2:********8766:w5o4vxx4f0/*/*"
}
}
},
{
"Sid": "lambda-da48f6d0-6d3c-4bbf-a761-ca3510f79624",
"Effect": "Allow",
"Principal": {
"Service": "cognito-sync.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-2:********8766:function:cakebook-api-dev-list",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:cognito-identity:us-east-2:********8766:identitypool/us-east-2:d9e4e505-c64a-4836-8e56-3af843dbe453"
}
}
}
]
}
You need to update Lambda permission to allow invoking by Cognito user pool.
Option A - update permission in JSON format
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "lambda-something",
"Effect": "Allow",
"Principal": {
"Service": "cognito-sync.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:eu-west-1:__accountId__:__function_name__",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:cognito-identity:eu-west-1:__accountId__:identitypool/eu-west-1:....."
}
}
}
]
}
Option B - in console
Go to Lambda Configuration page
Add trigger Cognito Sync Trigger
During saving it will offer to configure Lambda permission automatically - agree

How to share a folder via S3 bucket policy in federated identities context?

If you want to create a central storage for logs coming from many AWS accounts and share these logs respectively with their owners, this official AWS knowledge article explains how to do this very well with IAM based users.
However, I fail to understand how to do same if you use federated identities (SAML).
Let's assume you have accounts 111111111111 and 222222222222 logging to a bucket in the account 999999999999. For simplicity, let's reference these as A1, A2 and A9.
Further, accounts A1 and A2 can be accessed by federated users allowed to assume the role ADMIN, and have CloudTrails logging to the bucket BUCKET in A9.
So I have so far the following bucket policy. For simplicity, statement blocks have got Sids (statement IDs) 1,2,3 and 4.
The problem:
ADMIN from A1 can explore the folder structure in the bucket folder *AWSLogs/111111111111/** but an attempt to download an objects leads to the "access denied" error.
How comes? What is missing?
{
"Version": "2012-10-17",
"Statement": [
{
"Sid":"1",
"Effect": "Allow",
"Principal": {
"Service": "cloudtrail.amazonaws.com"
},
"Action": "s3:GetBucketAcl",
"Resource": "arn:aws:s3:::BUCKET"
},
{
"Sid":"2",
"Effect": "Allow",
"Principal": {
"Service": "cloudtrail.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": [
"arn:aws:s3:::BUCKET/AWSLogs/111111111111/*",
"arn:aws:s3:::BUCKET/AWSLogs/222222222222/*"
],
"Condition": {
"StringEquals": {
"s3:x-amz-acl": "bucket-owner-full-control"
}
}
},
{
"Sid":"3",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:role/ADMIN"
},
"Action": [
"s3:List*"
],
"Resource": "arn:aws:s3:::BUCKET",
"Condition": {
"StringLike": {
"s3:prefix": "AWSLogs/111111111111/*"
}
}
},
{
"Sid":"4",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:role/ADMIN"
},
"Action": [
"s3:List*",
"s3:Get*"
],
"Resource": "arn:aws:s3:::BUCKET/AWSLogs/111111111111/*"
}
]
}

S3 Bucket Policy to Allow access to specific roles and restrict all

I want to restrict access to a S3 bucket to all roles except select few roles using S3 Bucket policy.but here while i am switching into my writer and reader role its access denied.
Bucket Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::581262627839:role/Rk-S3-Reader-I-Role"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::rkimpdocs"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::581262627839:role/Rk-S3-Writer-I-Role"
},
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::rkimpdocs/*"
},
{
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::rkimpdocs",
"arn:aws:s3:::rkimpdocs/*"
],
"Condition": {
"ForAllValues:StringEquals": {
"aws:TagKeys": [
"JD",
"devops"
]
}
}
}
]
}
IAM Role Permission for writer role (Rk-S3-Writer-I-Role)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::rkimpdocs"
]
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::rkimpdocs",
"arn:aws:s3:::rkimpdocs/*"
]
}
]
}
Output :
Access denied on both bucket policy and switching into mention role. Any help / suggestion would be helpful.
An explicit Deny will override any Allow. In your policies, the Deny in the bucket policy is causing the access denied. To give access to specific IAM roles and denying others, you should use "NotPrincipal" element. Please refer this blog which explains your exact use case.
Also, "aws:Tagkeys" condition is not supported in S3, so you have to omit that as well.

Can not add AWS Resource level permissions to an Particular EC2 Instance

Referring to this Doc
I have created IAM policy which allows accessing only one EC2 Instance.And I have created an IAM user with the policy with that policy. But when I logged in with that user into my AWS account I got the Error "An error occurred fetching instance data: You are not authorized to perform this operation."
Policy document:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ec2:*"
],
"Condition": {
"StringEquals": {
"ec2:ResourceTag/test": "test"
}
},
"Resource": [
"arn:aws:ec2:us-east-1:AccountNumber:instance/*
],
"Effect": "Allow"
}
]
}
You must add EC2 describe to describe all EC2 resources, then base on other statement to filter resource by tag.
But with this policy, other IAM account still viewable other EC2 instances without any permission.
Here is what you need.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1507182214000",
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Condition": {
"StringEquals": {
"ec2:ResourceTag/TAG_NAME": "TAG_VALUE"
}
},
"Resource": [
"arn:aws:ec2:AWS_REGION:AWS_ACCOUNT:instance/*"
]
},
{
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:DescribeTags"
],
"Resource": "*"
},
{
"Effect": "Deny",
"Action": [
"ec2:CreateTags",
"ec2:DeleteTags"
],
"Resource": "*"
}
]
}