Amazon cognito Identity ID (sub) + S3 bucket name - amazon-s3

I am currently working on a webApp to let authenticated users (by Cognito User Pool) to handle their own s3 bucket. In this way, I would like to use the following variable ${cognito-identity.amazonaws.com:sub} in order to dynamically name my s3 buckets.
This is what I am expecting about my s3 role linked to my authenticated users from my Cognito federated identities :
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::${cognito-identity.amazonaws.com:sub}/*"
]
}
]
}
The value of ${cognito-identity.amazonaws.com:sub} looks like "eu-west-2:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx", but I know S3 name cannot contain ":" special character...
Is there any workaround in order to dynamically name my s3 buckets based on each cognito Identity ID ?
Looking forward any tips/advices :)

As #Rasikh mentions in his comment, there are limits to the number of S3 buckets per account. 100 by default, although you can get that increased to a maximum of 1,000 by submitting a service limit request to AWS. However, the solution is not scalable to any number of users.
A more common pattern is to create just a single s3 bucket, and only give each authenticated user the permissions to access a certain prefix (path or folder) based on their cognito identity's sub property.
The following policy (taken from Example 2 of the Access Policy Examples) gives a cognito web identity s3:ListBucket permission, but only for their particular prefix, and the ability to get and put objects, but again only inside their prefix.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["s3:ListBucket"],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket"],
"Condition": {"StringLike": {"s3:prefix": ["${cognito-identity.amazonaws.com:sub}/*"]}}
},
{
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": ["arn:aws:s3:::mybucket/${cognito-identity.amazonaws.com:sub}/*"]
}
]
}
It's worth noting that this will only work for authenticated users, as unauthenticated users will get a different cognito identity, as thus a different sub, each time.

Related

Grant cross account access to dynamodb table without using sts:AssumeRole

Essentially, I want an Iam role from AccountA to be able to manage a dynamodb table in AccountB, but the deployment that I am using does not support sts:AssumeRole (not my choice). I faced this same issue with an S3, but I was able to add an S3 bucket policy that allowed the Iam role from AccountB to access it (see below). Is there anything similar for dynamodb tables?
Thanks all :D
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::AccountB:role/iam-role-name"
},
"Action": "*",
"Resource": [
"arn:aws:s3:::bucket-name",
"arn:aws:s3:::bucket-name/*"
]
}
]
}
The only way that you can manage a table in another account is by assuming a role.
Unlike S3, DynamoDB does not support resource based access control. Unfortunately there are no simple workarounds as IAM is a security feature.

AWS restrict access to S3 bucket to single Amazon Cognito user

I'd like to implement the following: a specific Cognito (authenticated) user must have access to a single S3 bucket.
What is the best way to achieve the above?
I have tried the following:
Create Cognito User Pool with App integration
Create Cognito Identity Pool, which creates a dedicated IAM role on autenticated users
My idea was to update the policy of the Identity-Pool-IAM role to impose restrictions on S3 buckets to specific users only. I would of course have to extend this policy every time I add a new Cognito user (no problem with this).
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"mobileanalytics:PutEvents",
"cognito-sync:*",
"cognito-identity:*"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::BUCKET_NAME"
],
"Condition": {
"StringLike": {
"cognito-identity.amazonaws.com:sub": "COGNITO_USER_SUB_UID"
}
}
}
]
}
AWS doesn't like the way the S3-related policy above is written. It returns:
This policy defines some actions, resources, or conditions that do
not provide permissions. To grant access, policies must have an action
that has an applicable resource or condition.
Question: am I taking the right approach? If so, what am I doing wrong? If not, how should I solve my (supposedly simple) requirement?
For whatever reason, all the examples I have found seem to restrict access to an S3 folder in a bucket rather than the bucket itself (see here or here).

Invalid ARN error while creating S3 Bucket Policy using Policy generator

Im trying to create Amazon S3 Bucket Policy using the Policy Generator
Though this is very basic, but not sure why Im getting "Resource field is not valid. You must enter a valid ARN." for any ARN, eg for this "arn:aws:s3:::s3-demo-bucket-2022"
I have tried with multiple s3 bucket, aws accounts, all giving same problem.
Any help/suggestion?
As in your case, I just tried using the AWS bucket policy generator (located here)to build a simple S3 bucket policy, but it did not recognize the AWS-generated ARN I entered for my bucket. I tried several times, and it did not work, so it appears that at this moment, there might be a bug in AWS's system that is causing the policy generator to not recognize valid ARNs for S3 buckets.
You may have to build your own bucket policy using AWS examples, and enter it under "Bucket policy" (within the "Permissions" tab) of your S3 bucket. For instance, if you want to configure your S3 bucket policy to host a publicly accessible static website (which must be enabled by clicking the appropriate tick box for your bucket in the AWS console), you might enter this JSON policy, which worked in my case:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Principal": "*",
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": ["arn:aws:s3:::yourbucketname/*"]
}
]
}
If you go to edit the current policy (which might not yet exist), AWS will pre-populate most of this for you. Don't forget to add the "/*" to the end of your ARN (as I did here) if you want to specify access to the things IN the bucket as opposed to referring to the bucket itself.
Other JSON bucket policy examples are provided here by AWS:
https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html#example-bucket-policies-use-case-3
I have reported the bug in the policy generator website to AWS via my AWS console. I recommend you do the same so they will notice the problem and hopefully fix it.
Edit 1: I noticed you can bypass the apparent bug in the AWS Policy Generator by entering an asterisk ("*") where you would normally enter a specific S3 bucket ARN (the asterisk means 'any bucket'). This will enable you to finish building your policy, which you can edit near the end, inserting your specific bucket ARN in the place of the asterisk next to "Resource." So the editable policy will look something like this before you add your ARN (within double quotes and brackets as shown above):
{
"Id": "Policy1656274053828",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1656274051729",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "*",
"Principal": "*"
}
]
}
Just copy and paste the JSON policy into the place where you need it.

Prevent access of S3 bucket for admin via console

I have some very highly confidential data that i want to store in s3 bucket.
I want to make policies ( bucket or iam whatever required) in such a way that no one ( not even admin) can read the contents of files in that bucket from aws console.
But i will have a program running on my host that needs to put and get data from that s3 bucket.
Also i will be using server side encryption of s3 but i can't use client side encryption of s3.
You are looking for something like this;
{
"Id": "bucketPolicy",
"Statement": [
{
"Action": "s3:*",
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::111111111111:user/USERNAME",
"arn:aws:iam::111111111111:role/ROLENAME"
]
},
"Resource": [
"arn:aws:s3:::examplebucket",
"arn:aws:s3:::examplebucket/*"
]
}
],
"Version": "2012-10-17"
}
For test purposes make sure you replace arn:aws:iam::111111111111:user/USERNAME with your user arn. So in case you lock out everybody you can at least perform actions on the bucket.
arn:aws:iam::111111111111:role/ROLENAME should be replaced by the role arn which is attached to your EC2 instance (I am assuming that is what you mean by host).

Getting AWS Lambda access to private S3 resource

We have been trying to crack an issue with resource permissions related to S3 and Lambda.
We have a root account which inturn has -
Account A - Bucket owner
Account B - Used to upload (through CORS) and give access to S3 images
ROLE L - We have a lambda function which assigned this role with Full S3 access
The buckets have access policy like below -
{
"Version": "2012-10-17",
"Id": "Policyxxxxxxxxx",
"Statement": [
{
"Sid": "Stmt44444444444",
"Effect": "Deny",
"NotPrincipal": {
"AWS": [
"arn:aws:iam::xxxxxxxxxxxx:user/account-A",
"arn:aws:iam::xxxxxxxxxxxx:role/role-L"
]
},
"Action": [
"s3:*",
],
"Resource": [
"arn:aws:s3:::bucket",
"arn:aws:s3:::bucket/*"
]
}
]
}
The issue -
The lambda is able to access S3 resource only if object ACL is set to Public/read-only. But Lambda fails when the resource is set to 'private'.
Bucket policy just gives access to the bucket. Is there a way to give Role L read access to the resource?
Objects stored in Amazon S3 buckets are private by default. There is no need to use a Deny policy unless you wish to override another policy that grants access to the content.
I would recommend:
Remove your Deny policy
Create an IAM Role for your AWS Lambda function and grant permission to access the S3 bucket within that role.
Feel free to add a Bucket Policy for normal use as appropriate, but that should not impact your Lambda function's access that is granted via the Role.