In this recipe, we will learn to use pre-signed URLs from the CLI and then via the Python SDK. We can grant temporary permission to access S3 objects using pre-signed URLs with an expiry time. Currently, we cannot do this from the console. We have to do it through APIs from the CLI or by using an SDK.
S3 pre-signed URLs with an expiry time using the CLI and Python
Getting ready
We need a working AWS account with the following resources configured:
- A bucket and a file in it: I will be using a bucket name awsseccookbook with a file named mission-impossible.txt. Replace them with your bucket name and filename.
- A user with administrator permission on S3: We will configure a CLI profile for this user. I will be calling both the user and the CLI profile awssecadmin.
To execute the Python code, we need to install Python and Boto3 in the following order:
- Install python3.
- Install boto3 (if pip3 is installed, you can install boto3 as follows:
pip3 install boto3
How to do it...
We will first create a pre-signed URL from the CLI and then use the Python SDK.
Generating a pre-signed URL from the CLI
We can create a pre-signed URL from the CLI and test it as follows:
- Pre-sign a URL from the CLI as follows:
aws s3 presign s3://awsseccookbook/image-heartin-k.png \
--expiry 100 \
--profile awssecadmin
This command will output a signed URL with an expiry time:
- Copy and paste the URL and run it from a browser within the specified time. We should be able to see the contents of our file:
If we run the URL after the specified time, we should get an access denied error message:
Next, we will look at how to do pre-signing using the Python SDK.
Generating a pre-signed URL using the Python SDK
We can create a pre-signed URL using the Python SDK and test it as follows:
- Create a file named s3presign.py with the following code:
import boto3
boto3.setup_default_session(profile_name='awssecadmin')
s3_client = boto3.client('s3')
url = s3_client.generate_presigned_url('get_object', Params={'Bucket': 'awsseccookbook', 'Key': 'mission-impossible.txt'}, ExpiresIn=300)
print(url)
- Execute the code as python3 s3presign.py:
This will return the pre-signed URL:
Run the URL from a browser (much as we did in the previous section) before and after the specified time.
How it works...
In the Generating a pre-signed URL from the CLI section, we pre-signed a URL from the CLI. In the Generating a pre-signed URL using the Python SDK section, we pre-signed a URL using the Python SDK. We used the boto3 library for our Python SDK demo. Boto is the AWS SDK for Python. It facilitates the creation, configuration, and management of AWS services, such as EC2 and S3 using Python.
Most APIs related to pre-signing will accept the following data for generating pre-signed, timed URLs:
- Bucket and object
- Expiry date and time
- HTTP method
- Security credentials
In this recipe, we specified the bucket, object, and expiry in code. The HTTP operation was GET. For security credentials, we specified a user profile that has permissions for the operation, which was get_object in our case. Anyone with valid credentials can generate a pre-signed URL. However, if the user does not have permission to perform the intended operation (for example, get_object), then the operation will eventually fail.
There's more...
In this recipe, we generated pre-signed URLs using both CLI commands and Python code. The following code snippet shows how pre-signing can be done from Java:
GeneratePresignedUrlRequest generatePresignedUrlRequest = new
GeneratePresignedUrlRequest(bucketName, objectKey)
.withMethod(HttpMethod.PUT)
.withExpiration(expiration);
URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
You can follow the AWS documentation to do the same with other supported SDKs as well.
See also
- Refer to the following link for more use cases for Python and Boto3 related to pre-signed URLs: https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-presigned-urls.html.