Cross account role granting S3 bucket access - Permission Denied - amazon-web-services

I have two accounts, account ACCOUNTAAAA, and ACCOUNTBBBB. A bucket (BUCKETAAAA) exists in account ACCOUNTAAAA and an instance with a role (ROLEBBBB) in ACCOUNTBBBB needs to be able to read from it.
I have adding the following permissions to the bucket:
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNTBBBB:role/ROLEBBBB"
},
"Action": [
"s3:*"
],
"Resource": "arn:aws:s3:::BUCKETAAAA/*"
}
I have the following permissions on the role in ACOUNTBBBB:
"Sid": "",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::BUCKETAAAA/",
"arn:aws:s3:::BUCKETAAAA/*"
]
}
My assumption is I should be able to run aws s3 ls s3://BUCKETAAAA on the EC2 instance with the IAM role attached, and see the contants of BUCKETAAAA. When I try this, I get An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied.
What am I missing here?

To reproduce your situation, I did the following:
Created Role-B in Account-B with EC2 as the Trusted Entity ("Allows EC2 instances to call AWS services on your behalf") and a policy granting access to Bucket-A
Created Bucket-A in Account-A
Added a Bucket Policy to Bucket-A, which grants access to Role-B
Assigned Role-B to an Amazon EC2 instance
The Bucket Policy on Bucket-A was:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<account>:role/role-b"
},
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::bucket-a",
"arn:aws:s3:::bucket-a/*"
]
}
]
}
The permissions on Role-B were:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BucketA",
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::bucket-a",
"arn:aws:s3:::bucket-a/*"
]
}
]
}
I was able to successfully use aws s3 ls s3://bucket-a and was able to copy files to Bucket-A.
The main difference I see with your attempt was that your Bucket Policy only granted permissions for:
"Resource": "arn:aws:s3:::BUCKETAAAA/*"
This means "anything within Bucket-A" but does not include Bucket-A itself. The command aws s3 ls s3://BUCKETAAAA operates on the bucket, for which the role has no permissions.
Thus, you should also add permissions for the bucket itself:
"Resource": [
"arn:aws:s3:::BUCKETAAAA",
"arn:aws:s3:::BUCKETAAAA/*"

Related

Deploy Lambda with code source from another accounts s3 bucket

I store my Lambda zip files in an S3 bucket in Account A. In Account B I have my Lambda. I am trying to have my Lambda use the zip file in Account A's bucket but I keep getting:
Your access has been denied by S3, please make sure your request credentials have permission to GetObject for bucket/code.zip. S3 Error Code: AccessDenied. S3 Error Message: Access Denied
I have followed guides I have found online but I am still facing issues.
Here is my current config:
Account A's S3 Bucket Policy:
{
"Version": "2012-10-17",
"Id": "ExamplePolicy",
"Statement": [
{
"Sid": "ExampleStmt",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::AccountBID:role/MyLambdaRole"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::bucket",
"arn:aws:s3:::bucket/*"
]
}
]
}
Account B's Lambda Execution Role Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::bucket/*",
"arn:aws:s3:::bucket"
]
}
]
}
The principal in your bucket policy is the role that AWS Lambda uses during execution, which is not used when deploying your function. You could easily just allow the entire B account principal in the bucket policy and then use IAM policies in account B to allow access to the bucket that way.
A bucket policy allowing an entire account looks like this:
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "ProductAccountAccess",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::XXXX-account-number:root"
]
},
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::bucket",
"arn:aws:s3:::bucket/*"
]
}
]
}
This means that the IAM policies in account B depend on how you do your deployment. Meaning that whatever credentials are used for the deployment need to have S3 permissions for that bucket.

PutObject access denied for a cross account setup

I am setting up a cross-account between two AWS accounts, and I'd like account B to be able to push files/logs to account A. I have an S3 bucket encrypted with KMS encryption sitting in account A.
The bucket in account A has the attached policy in it:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::00000000:role/some-role-in-account-B"
},
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3::some-bucket-in-account-A",
"arn:aws:s3:::some-bucket-in-account-A/*"
]
}
]
}
In account B, I have created a role (some-role-in-account-B) with the below policy attached:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::some-bucket-in-account-A",
"arn:aws:s3:::some-bucket-in-account-A/*"
]
}
]
}
I have an instance in account B in which I have attached the some-role-in-account-B role.
Running these from the instance: aws s3 ls s3://some-bucket-in-account-A works fine. However, aws s3 cp some-random-file s3://some-bucket-in-account-A fails with the error: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied. Does anyone knows what I might be missing?
You need to grant the role from account B access to the KMS key. See here for more information: https://aws.amazon.com/premiumsupport/knowledge-center/cross-account-access-denied-error-s3/
Mind you, I don't think you need to grant all the permissions referenced in the article to the role, you should only need to grant the following:
kms:Encrypt
kms:GenerateDataKey
kms:ReEncrypt*

How to give external AWS IAM user access to specific S3 Bucket folder

I need to give external users access to a single Amazon S3 bucket folder. I have their ARN information but I am having an issue granting access.
{
"Version": "2012-10-17",
"Id": "S3AccessPolicy",
"Statement": [
{
"Sid": "TestAccess",
"Effect": "Allow",
"Principal": {
"AWS": "<external ARN>"
},
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::rootlevelbucket",
"arn:aws:s3:::rootlevelbucket/specificfolder/*"
]
}
]
}
There is 2 sides to cross account access. You have the first part with the bucket policy, but the admin for the external account needs to grant the user access to the S3 with a IAM policy like below. You can use the s3:* on the IAM policy because you bucket policy will restrict to just the commands you list.
AWS Documentation
IAM Policy for external user:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RootlevelbucketAccess",
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::rootlevelbucket",
"arn:aws:s3:::rootlevelbucket/specificfolder/*"
]
}
]
}

AWS S3: An error occurred (AccessDenied) when calling the GetObject operation: Access Denied

I have an AWS account with read/write permissions as shown below:
I'd like to make it so that an IAM user can download files from an S3 bucket but I'm getting access denied when executing aws s3 sync s3://<bucket_name> . I have tried various things, but not to avail. Some steps that I did:
Created a user called s3-full-access
Executed aws configure in my CLI and entered the generated access key id and secret access key for the above user
Created a bucket policy (shown below) that I'd hoped grants access for my user created in first step.
My bucket has a folder name AffectivaLogs in which files were being added anonymously by various users, and it seems like though the bucket is public, the folder inside it is not and I am not even able to make it public, and it leads to following error.
Following are the public access settings:
Update: I updated the bucket policy as follows, but it doesn't work.
To test the situation, I did the following:
Created an IAM User with no attached policies
Created an Amazon S3 bucket
Turned off S3 block public access settings:
Block new public bucket policies
Block public and cross-account access if bucket has public policies
Added a Bucket Policy granting s3:* access to the contents of the bucket for the IAM User
I then ran aws s3 sync and got Access Denied.
I then modified the policy to also permit access to the bucket itself:
{
"Id": "Policy",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "statement",
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::my-bucket/*",
"arn:aws:s3:::my-bucket"
],
"Principal": {
"AWS": [
"arn:aws:iam::123456789012:user/stack-user"
]
}
}
]
}
This worked.
Bottom line: Also add permissions to access the bucket, in addition to the contents of the bucket. (I suspect it is because aws s3 sync requires listing of bucket contents, in addition to accessing the objects themselves.)
If you use KMS encryption enabled on bucket you should also add policy that allows you to decrypt data using KMS key.
You can configure the S3 policy with the required principal
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListBucket",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::accountId:user/*
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::bucket"
},
{
"Sid": "GetObjects",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::accountId:user/*
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucket/*"
}
]
}
Or you can create IAM policy and attached it to the role
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListBucket",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::bucket"
},
{
"Sid": "GetObject",
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::bucket/*"
}
]
}

Connecting Amazon S3 bucket to Other Server - IAM

I am trying to connect Amazon S3 to other services through Bucket policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"arn:aws:iam::ACCOUNT-ID:user/augmen",
}
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:GetObject"
],
"Resource": ["arn:aws:s3:::rajatv.input",
"arn:aws:s3:::rajatv.input/*"]
}
]
}
Still getting errors like:
This policy contains invalid Json
Invalid Bucket syntax
No Resources
It appears that you are wanting to give bucket access to a specific IAM User. If so, the best way is to put a policy on the IAM User themselves, so that the permissions apply only to them.
This policy would grant bucket access to whichever user has it as an IAM policy. To add it, go to the user, Add Inline Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PermitBucketAccess",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::rajatv.input",
"arn:aws:s3:::rajatv.input/*"
]
}
]
}
Bucket Policies, which are applied to the bucket itself, are best used to grant access to everyone, whereas an IAM policy is best for granting permissions to specific IAM Users, Groups and Roles.
Principal needs to have this format:
"Principal": {"AWS": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:root"]},