What bucket permissions are required to download zip file directly from URL? - amazon-web-services

I am following a tutorial here and if I take this s3 URL from the tutorial, https://s3.eu-central-1.amazonaws.com/deepset.ai-farm-qa/datasets/documents/wiki_gameofthrones_txt.zip, I am able to directly download the zip file to local.
When I subsistute my own zip file URL, I get an error that BadZipFile: File is not a zip file, and if I try my URL for zip file, I get permission denied instead of being able to download.
I also confirmed the zip files are formated correctly using terminal: unzip -t zipfile.zip
What permissions do I need to change in s3 or on the s3 object to allow download of zip file directly from URL?
Still very new to IAM s3 permissions and current permission are the standard ones when creating bucket.

Objects in Amazon S3 are private by default. This means that they cannot be accessed by an anonymous URL (like you have shown).
If you want a specific object to be publicly available (meaning that anyone with the URL can access it), then use the Make Public option in the S3 management console. This can also be configured at the time that the object is uploaded by specifying ACL=public-read.
If you want a whole bucket, or particular paths within a bucket, to be public, then you can create a Bucket Policy that grants access to the bucket. This requires S3 Block Public Access to be disabled.
You can also generate n Amazon S3 pre-signed URL, which provides time-limited access to a private object. The pre-signed URL has additional information added that grants permission to access the private object. This is how web applications provide access to private objects to authorized users, such as photo websites.
If an object is accessed via an AWS API call or the AWS Command-Line Interface (CLI), then AWS credentials are used to identify the user. If the user has permission to access the object, then they can download it. This method uses an API call rather than a URL.

Two solutions:
Make your bucket/file public. Check this ( Not recommended)
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"PublicRead",
"Effect":"Allow",
"Principal": "*",
"Action":["s3:GetObject","s3:GetObjectVersion"],
"Resource":["arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"]
}
]
}
Use pre-signed URLs with SDK .. check this
var params = {Bucket: bucketname , Key: keyfile , Expires: 3600 , ResponseContentDisposition : `attachment; filename="filename.ext"` };
var url = s3.getSignedUrl('getObject', params);

Related

AWS S3 file upload access denied in php codeigniter

unable to upload files to aws s3 bucket shows "
A PHP Error was encountered
Severity: User Warning
Message: S3::putObject(): [AccessDenied] Access Denied
Filename: libraries/S3.php"
There are two ways to solve this problem-
If your Bucket permission "Bucket and object not public"
First, you need to change the permission in AWS S3
Go to Bucket->permission->edit
Uncheck
- Block new public ACLs and uploading public object
- Remove public access granted through public ACLs
Now try to upload, I hope it will work.
Use "S3::ACL_PRIVATE" in your putObjectFile function parameter at the time of upload file. ACL_PRIVATE and other keys are declared in the s3.php library file.
$saved = $this->s3->putObjectFile($file_path,
$this->bucket_name,
$this->folder_name.$s3_file,
S3::ACL_PRIVATE,
array(),
$mime_type);
Now try to upload.

Amazon S3 File Permissions, Access Denied when copied from another account

I have a set of video files that were copied from one AWS Bucket from another account to my account in my own bucket.
I'm running into a problem now with all of the files where i am receiving Access Denied errors when I try to make all of the files public.
Specifically, I login to my AWS account, go into S3, drill down through the folder structures to locate one of the videos files.
When I look at this specificfile, the permissions tab on the files does not show any permissions assigned to anyone. No users, groups, or system permissions have been assigned.
At the bottom of the Permissions tab, I see a small box that says "Error: Access Denied". I can't change anything about the file. I can't add meta-data. I can't add a user to the file. I cannot make the file Public.
Is there a way i can gain control of these files so that I can make them public? There are over 15,000 files / around 60GBs of files. I'd like to avoid downloading and reuploading all of the files.
With some assistance and suggestions from the folks here I have tried the following. I made a new folder in my bucket called "media".
I tried this command:
aws s3 cp s3://mybucket/2014/09/17/thumb.jpg s3://mybucket/media --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers full=emailaddress=my_aws_account_email_address
I receive a fatal error 403 when calling the HeadObject operation: Forbidden.
A very interesting conundrum! Fortunately, there is a solution.
First, a recap:
Bucket A in Account A
Bucket B in Account B
User in Account A copies objects to Bucket B (having been granted appropriate permissions to do so)
Objects in Bucket B still belong to Account A and cannot be accessed by Account B
I managed to reproduce this and can confirm that users in Account B cannot access the file -- not even the root user in Account B!
Fortunately, things can be fixed. The aws s3 cp command in the AWS Command-Line Interface (CLI) can update permissions on a file when copied to the same name. However, to trigger this, you also have to update something else otherwise you get this error:
This copy request is illegal because it is trying to copy an object to itself without changing the object's metadata, storage class, website redirect location or encryption attributes.
Therefore, the permissions can be updated with this command:
aws s3 cp s3://my-bucket/ s3://my-bucket/ --recursive --acl bucket-owner-full-control --metadata "One=Two"
Must be run by an Account A user that has access permissions to the objects (eg the user who originally copied the objects to Bucket B)
The metadata content is unimportant, but needed to force the update
--acl bucket-owner-full-control will grant permission to Account B so you'll be able to use the objects as normal
End result: A bucket you can use!
aws s3 cp s3://account1/ s3://accountb/ --recursive --acl bucket-owner-full-control
To correctly set the appropriate permissions for newly added files, add this bucket policy:
[...]
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012::user/their-user"
},
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::my-bucket/*"
}
And set ACL for newly created files in code. Python example:
import boto3
client = boto3.client('s3')
local_file_path = '/home/me/data.csv'
bucket_name = 'my-bucket'
bucket_file_path = 'exports/data.csv'
client.upload_file(
local_file_path,
bucket_name,
bucket_file_path,
ExtraArgs={'ACL':'bucket-owner-full-control'}
)
source: https://medium.com/artificial-industry/how-to-download-files-that-others-put-in-your-aws-s3-bucket-2269e20ed041 (disclaimer: written by me)
In case anyone trying to do the same but using Hadoop/Spark job instead of AWS CLI.
Step 1: Grant user in Account A appropriate permissions to copy
objects to Bucket B. (mentioned in above answer)
Step 2: Set the fs.s3a.acl.default configuration option using Hadoop Configuration. This can be set in conf file or in program:
Conf File:
<property>
<name>fs.s3a.acl.default</name>
<description>Set a canned ACL for newly created and copied objects. Value may be Private,
PublicRead, PublicReadWrite, AuthenticatedRead, LogDeliveryWrite, BucketOwnerRead,
or BucketOwnerFullControl.</description>
<value>$chooseOneFromDescription</value>
</property>
Programmatically:
spark.sparkContext.hadoopConfiguration.set("fs.s3a.acl.default", "BucketOwnerFullControl")
by putting
--acl bucket-owner-full-control
made it to work.
I'm afraid you won't be able to transfer ownership as you wish. Here's what you did:
Old account copies objects into new account.
The "right" way of doing it (assuming you wanted to assume ownership on the new account) would be:
New account copies objects from old account.
See the small but important difference? S3 docs kind of explain it.
I think you might get away with it without needing to download the whole thing by just copying all of the files within the same bucket, and then deleting the old files. Make sure you can change the permissions after doing the copy. This should save you some money too, as you won't have to pay for the data transfer costs of downloading everything.
boto3 "copy_object" solution :
Providing Grant control to the destination bucket owner
client.copy_object(CopySource=copy_source, Bucket=target_bucket, Key=key, GrantFullControl='id=<bucket owner Canonical ID>')
Get for console
Select bucket, Permission tab, "Access Control List" tab

AWS CLI s3 copy fails with 403 error, trying to administrate a user-uploaded object

Trying to copy a file from an S3 bucket to my local machine:
aws s3 cp s3://my-bucket-name/audio-0b7ea3d0-13ab-4c7c-ac66-1bec2e572c14.wav ./
fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden
Things I have confirmed:
I'm using version aws-cli/1.11.13 Python/3.5.2 Linux/4.4.0-75-generic botocore/1.4.70
The S3 Object key is correct. I have copied it directly from the S3 web interface.
The AWS CLI is configured with valid credentials. I generated a new key/secret pair. I deleted the ~/.aws folder before re-configuring the aws cli. The IAM web interface online confirms that the user specific by arn is in fact making use of S3 via the CLI.
The IAM user is granted the S3 full access managed policy, per this SO post. I removed all this users' policies, and then added only the AWS managed policy called AdministratorAccess, which includes "S3, Full access, All resources." Is there a different way to grant access via the CLI? I did not believe so.
Bucket policy is intended to grant wide open access:
{
"Sid": "AdminAccess",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:*"
],
"Resource": [
"arn:aws:s3:::my-bucket-name",
"arn:aws:s3:::my-bucket-name/*"
]
}
How did I upload this object?
I uploaded this object using AWS Signature v4 signed upload policy from a web app in the client browser directly to AWS.
It turns out, looking at the object properties, I can see the Owner of the OBJECT is "Anonymous," and also "Anonymous" user has full permission to this object.
I believe this is why I'm not able to access this object (I'm authenticated). Example: Since the "Anonymous" user has full permission, I am able to access via GET using a Web browser. This is functioning as designed. The S3 bucket is for uploading files which then become available for public consumption.
So when the file is POST'ed with the upload policy, the resulting owner is "Anonymous".
In this case, acl=bucket-owner-full-control should be used while uploading the object so the bucket owner can control the object.
Doing this, the owner will still be "Anonymous", however, it'll give the bucket owner (me) the full permission and I should be able to access the object after that, via AWS CLI.
Note that acl=ec2-bundle-read is a default that's actually hard-coded into the latest AWS SDK. See https://github.com/aws/aws-sdk-java/blob/7844c64cf248aed889811bf2e871ad6b276a89ca/aws-java-sdk-ec2/src/main/java/com/amazonaws/services/ec2/util/S3UploadPolicy.java#L77
It was necessary to copy S3UploadPolicy.java into my own codebase (it's an entirely portable little utility class, it turns out) and modify it in order to use acl=bucket-owner-full-control. And I have verified that this affords the administration of uploaded objects via AWS CLI.
In my case I have 3 accounts (A1, A2, A3) with 3 canonical users (canonical_user_account_A1, canonical_user_account_A2, canonical_user_account_A3) and 1 IAM role (R1) that is in A3.
Files are in a bucket in A2 and the files owner is canonical_user_account_A1 (this is on purpose). When I tried to list the files I didn't got any error, BUT when I tried to download one of them I got
fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden
I have added List and Get permissions for a R1 in the bucket policy and in the role permissions, in this case this is not enough, if the account were the bucket is not the owner it can't allow users from other account to get (download) files. So I needed to make sure that when I upload files I'm using:
access_control_policy = {
'Grants': [
{
'Grantee': {
'ID': canonical_user_account_A2,
'Type': 'CanonicalUser'
},
'Permission': 'READ'
},
{
'Grantee': {
'ID': canonical_user_account_A3,
'Type': 'CanonicalUser'
},
'Permission': 'READ'
},
],
'Owner': {
'ID': canonical_user_account_A1
}
}
upload_extra_args = {'ACL': 'bucket-owner-full-control'}
s3_client.upload_file(file_path, bucket_name, s3_file_path, ExtraArgs=upload_extra_args)
s3_client.put_object_acl(AccessControlPolicy=access_control_policy, Bucket=bucket_name, Key=s3_file_path)
This allow both canonical_user_account_A2 and canonical_user_account_A3 to read and download the file.
I ran into a similar permissions issue when trying to download from s3 something I had uploaded previously. Turns out it has nothing to do with the bucket policy and everything to do with how your credentials are set when you upload and how you grant access privileges at time of upload. See this for more information on several ways to solve the problem.
In my case above error appeared when machine that was trying to contact S3 had system time far from the current one. Setting a correct time helped.
AWS S3 will return you Forbidden(403) even if file does not exist for security reasons.
Please ensure you have given proper s3 path while downloading.
You can read more about it here

Access Denied error with Amazon S3

I'm getting an Access Denied error with Amazon S3 and can't figure out why.
My settings are as follows:
STATIC_URL = 'http://s3.amazonaws.com/%s/' % AWS_STORAGE_BUCKET_NAME
What would cause an access denied error? I have verified that my keys are correct.
The URL you show above would resolve to a bucket within S3. In order to access that bucket successfully with such a URL, the permissions on the bucket would have to grant 'public-read' access to the bucket. In addition, each object or file within the bucket would have to grant 'public-read' access, as well.
Do you want the bucket and all content within the bucket to be readable by anyone? If so, make sure the permissions are set appropriately. Note, however, that granting 'public-read' to the bucket itself will allow anyone to list the contents of the bucket. That's usually unnecessary and probably should be avoided.
Also note that the keys (I assume you mean your AWS access key and secret key) only apply when you are accessing S3 via the API. If you simply access it with the URL via a browser, the credentials are not used in the request.

How to restrict folders to user

Thanks for previous replies.
Is it possible to restrict the user to view particular folder in a bucket. let us take example, i have a bucket and it contains 2 folder, User A have only privilege to view first folder of the bucket, if he tries to access another folder it has to show access denied. is this possible to do in amazon S3.
You can do this using AWS Identity and Access Management (IAM). You can use this to create multiple identities and assign various permissions to those identities.
Here's a relevant example taken from the Amazon docs:
Example 1: Allow each user to have a home directory in Amazon S3
In this example, we create a policy that we'll attach to the user
named Bob. The policy gives Bob access to the following home directory
in Amazon S3: my_corporate_bucket/home/bob. Bob is allowed to access
only the specific Amazon S3 actions shown in the policy, and only with
the objects in his home directory.
{
"Statement":[{
"Effect":"Allow",
"Action":["s3:PutObject","s3:GetObject","s3:GetObjectVersion",
"s3:DeleteObject","s3:DeleteObjectVersion"],
"Resource":"arn:aws:s3:::my_corporate_bucket/home/bob/*"
}
]
}