AWS S3 bucket policy to external account denies access - amazon-web-services

I have created an S3 bucket which we will call mytest-bucket where I am trying to grant access to the bucket and its objects to an IAM user at a different company, not within my organization. The user, which we call Bob has given me their account ID, IAM username, and canonical ID. I've done the following to attempt to grant Bob access:
1) I have set the bucket policy for mytest-bucket as such:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::111111111111:root",
"arn:aws:iam::111111111111:user/Bob"
]
},
"Action": [
"s3:*",
"s3:ListBucket",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::mytest-bucket",
"arn:aws:s3:::mytest-bucket/*"
]
}
]
}
2) I have set my Individual Block Public Access settings for this bucket to the following:
3) I have also granted List, Write ACL permissions to the External account using the Canonical ID provided, as well as Read, Write Bucket ACL permissions. For object ownership, I have ACLs are enabled and can be used to grand access to this bucket and its objects.
Yet, still, Bob is unable to both 1) see the bucket listed under their account, 2) access any objects or the bucket itself due to Access Denied error.
Is there something I can change in the above configuration to provide Bob access to this one bucket and it's objects?
How can I help them get access?
Edit: Bob will not be uploading objects, but only reading and downloading objects from this bucket.

You say that "bob is unable to see the bucket listed under their account". This is normal -- the bucket does not belong to his account, so it will not be listed when he uses the S3 management console. However, Bob should be able to access it when using the AWS CLI, such as:
aws s3 ls s3://mytest-bucket
If Bob really wants to see it in the console, he can 'cheat' by using a URL that will show the bucket, but Bob would need to paste the URL directly rather than going through the bucket hierarchy. To demonstrate, here is a URL that would normally show a bucket:
https://us-east-1.console.aws.amazon.com/s3/buckets/mytest-bucket
You can change the bucket name at the end to 'jump' directly to a desired bucket.

Related

S3 cross account permission (view via AWS UI and copy bucket content)

I'm trying to access (see it on my AWS console beside my own buckets) an external bucket ( bucket B ) and if possible copy it.
What permission (JSON file) do I need to ask from the owner of bucket B? is full read and full list permissions for my account enough? If I will receive the full read and the full list I will be able to see the bucket on my account under s3 buckets?
Example 2: Bucket owner granting cross-account bucket permissions - Amazon Simple Storage Service
Viewing / Downloading contents
The Amazon S3 management console only shows buckets in your own account.
However, you can 'cheat' and modify the URL to show another bucket for which you have access permission.
For example, when viewing the contents of a bucket in the S3 management console, the URL is:
https://us-east-1.console.aws.amazon.com/s3/buckets/BUCKET-NAME?region=ap-southeast-2&tab=objects
You can modify BUCKET-NAME to view a specific bucket.
Alternatively, you can access buckets via the AWS CLI, regardless of which account 'owns' the bucket, as long as you have sufficient permissions:
aws s3 ls s3://BUCKET-NAME
Required Permissions
The permissions you will need on the bucket depend totally on what you wish to do. If you want the ability to list the contents of the bucket, then you will need s3:ListBucket permission. If you want the ability to download an object, you will need s3:GetObject permission.
It would be something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::BUCKET-NAME",
"arn:aws:s3:::BUCKET-NAME/*"
],
"Principal": {
"AWS": [
"arn:aws:iam::111122223333:user/YOUR-USER-NAME"
]
}
}
]
}
When granting access, the owner of Bucket B will need to grant permissions to your IAM User (in your own AWS Account). Therefore, you will need to give them the ARN of your own IAM User.

Share Data between Companies using AWS S3 Public Access

I wanted to get huge amount of data from another organization to my organization.
I created an s3 bucket with name as: srikanth-poc-can-be-deleted.
This bucket under the access column is showing as "Public". All my other buckets are showing it as "Bucket and objects not public". (i.e. I disabled the option "Block All public access" under "Block Public access"). I also set up below policy.
and defined below bucket policy.
Question: Under the bucket, I have one folder: 'upload_here' and I am getting this folder URL so that any body can upload the files under this folder. However, its not working as expected. When I enter the folder URL in the browser, an empty file with the name of the folder is downloading and nothing happening. I was expecting it to open the folder, so that others could place their files in there. Could you please let me know what is the issue?
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::srikanth-poc-can-be-deleted/*"
},
{
"Sid": "Statement2",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::srikanth-poc-can-be-deleted"
}
]
}
If you want to copy data in Amazon S3 between AWS Accounts, you should use one of these methods below. They will ensure that your buckets, and your data, are kept private at all times.
Using source credentials
If you are using credentials from the source account:
Grant the IAM User permission to read from the source bucket and write to the destination bucket
Add a Bucket Policy on the destination bucket in the other account that grants access to the IAM User from the source account (similar to your policy above, but specifying the source IAM User as the Principal)
In the destination bucket, make sure ACLs are disabled so that the destination account 'owns' the objects
Use the AWS CLI to copy the objects, using the IAM User credentials
Using destination credentials
If you are using credentials from the destination account:
Grant the IAM User permission to read from the source bucket and write to the destination bucket
Add a Bucket Policy on the source bucket that grants access to the IAM User from the destination account (similar to your policy above, but specifying the destination IAM User as the Principal)
Use the AWS CLI to copy the objects, using the IAM User credentials

Grant access to Amazon S3 bucket only to one IAM User

I wish to have a bucket that only one IAM user could access using the AWS Console, list its content and access object files inside it.
So, I have created the IAM user, the bucket itself, and later:
bucket policy as follow:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "statement1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::0000000:user/dave"
},
"Action": [
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::testbucket1234"
},
{
"Sid": "statement2",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::0000000:user/dave"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::testbucket1234/*"
}
]
}
And also a inline policy attached to my user's group, as follow:
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:*Object",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::testbucket1234/*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*"
}
]
}
Now: I can list my buckets, access the desired bucket, list its content (so far so good). The problem is when I try to open one file object inside the bucket and I get "access denied" error. If I turn the object public, I can access it, but I can also access it using other IAM accounts, and that is not the intention. I want to access the bucket, list its contents and access objects only by usage of this specific IAM account. What am I doing wrong? How can I reach this goal? Thanks in advance.
By default, no IAM User can access any bucket. It is only by granting permissions to users that they can access resources.
However, many people tend to grant Amazon S3 permissions for all buckets, at least for Administrators. This then makes it difficult to remove permissions so that a bucket can only be accessed by one user. While it can be done with Deny policies, such policies are difficult to craft correctly.
For situations where specific data should only be accessed by one user, or a specific group of users (eg HR staff), I would recommend that you create a separate AWS Account and only grant permission to specific IAM Users or IAM Groups via a Bucket Policy (which works fine cross-account). This way, any generic policies that grant access to "all buckets" will not apply to buckets in this separate account.
Update: Accessing private objects
Expanding on what is mentioned in the comments below, a private object in Amazon S3 can be accessed by an authorized user. However, when accessing the object, it is necessary to identify who is accessing the object and their identity must be proved. This can be done in one of several ways:
In the Amazon S3 management console, use the Open command (in the Actions menu). This will open the object using a pre-signed URL that authorizes the access based upon the user who logged into the console. The same method is used for the Download option.
Using the AWS Command-Line Interface (CLI), you can download objects. The AWS CLI needs to be pre-configured with your IAM security credentials to prove your identity.
Programs using an AWS SDK can access S3 objects using their IAM security credentials. In fact, the AWS CLI is simply a Python program that uses the AWS SDK.
If you want to access the object via a URL, an application can generate an Amazon S3 pre-signed URLs. This URL includes the user's identity and a security signature that grants access to a private object for a limited period (eg 5 minutes). This method is commonly used when web applications want to grant access to a private object, such as a document or photo. The S3 management console actually uses this method when a user selects Actions/Open, so that the user can view a private object in their browser.

Cross-account S3 bucket permissions

I'm trying to grant access to S3 bucket to other account using S3 UI:
Permissions -> Access Control List -> Access for other AWS accounts
I know canonical id for account I want to grant permissions. It is 161 char code. When I'm trying to add It I'm getting next error:
I'm pretty sure I'm using the correct ID because it says says Canonical user ID (for Amazon S3)
What is wrong?
If you wish to grant bucket access to another AWS Account, I would recommend using a Bucket Policy. This allows the user(s) in the other account to use their normal credentials to access the bucket.
Here is a sample bucket policy that grants access to a specific user in another AWS account:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
],
"Principal": {
"AWS": [
"arn:aws:iam::ACCOUNT-ID:user/foo"
]
}
}
]
}
You are probably using the wrong id. Please have a look at this document to find out how to retrieve the one that you need here: AWS account identifiers - AWS General Reference
Having that said, in most cases it would be better to not use access control list but access S3 via cross-account roles instead. To learn more, please have a look at: Provide Cross-Account Access to Objects In S3 Buckets

File in Amazon S3 bucket denied after making bucket public

I have made my Amazon S3 bucket public, by going to its Permissions tab, and setting public access to everyone:
List objects
Write objects
List bucket permissions
Write bucket permissions
There is now an orange "Public" label on the bucket.
But when I go into the bucket, click on one of the images stored there, and click on the Link it provides, I get Access Denied. The link looks like this:
https://s3.eu-central-1.amazonaws.com/[bucket-name]/images/36d03456fcfaa06061f.jpg
Why is it still unavailable despite setting the bucket's permissions to public?
You either need to set Object Level Permissions on each object that you want to be available to the internet as Read Object.
or, you can use Bucket Policies to make this more widely permissioned, and not worry about resetting the permissions on each upload:
{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::www.example.com/*"
}
]
}