Unless you are hosting public files on S3, like your website’s static content, the chances are that you are going to keep your buckets private.
And that is great, but sometimes when working with private buckets, you may want to be able to allow access to someone else.
It could be for someone that doesn’t have privileges on that bucket, a different account, or maybe a customer who wants to download your latest software version.
It turns out there’s a way to grant temporary access to an S3 object in the form of a “pre-signed” URL.
A presigned URL allows whoever has this link to download the file from S3 and is valid for a certain amount of time. By default, it expires after an hour.
You can create presigned URLs in two ways:
- Using the AWS command line.
- The AWS SDK
I’ll walk you through two scenarios using these two methods, so you can get a better idea of how to use presigned URLs.
Using the command line
Let’s assume that you want to transfer a file from one AWS account to another but don’t want to mess around with IAM too much to create policies and then remember to remove them.
Or maybe you want to help out a co-worker doing an offline installation at a client’s office.
The fastest way to presign an object is by using the command:
aws s3 presign s3://pushbuildtestdeploy-demo/testing.txt
The result will be the URL:
You can see that the URL is valid for 1 hour. Note that everyone who has this link has access to the file, so think carefully about how you share it with others.
If you want to set a different expiration add the “–expires-in” flag, which is followed by the number of seconds.
aws s3 presign s3://pushbuildtestdeploy-demo/testing.txt --expires-in 600
Note the Amz-Expires=600 parameter.
Using the SDK
There are, of course, a few use cases for using the SDK for allowing temporary access to S3 objects.
Suppose that you want to give access to a digital product to people who made a purchase. Instead of making the bucket entirely open for the world or writing logic to restrict the access somehow in your code, you can use the SDK to return a temporary download link.
In Python, it’s as simple as calling the method:
generate_presigned_url(ClientMethod, Params=None, ExpiresIn=3600, HttpMethod=None)
Now the user can log in to the dashboard and download the file.
This could also be useful when information is generated for each client, and you don’t want to make the bucket public.
Yes, it’s tough to guess a filename with a hash, but this could be another layer of protection.