S3 Presigned URLs
Introduction
A presigned URL is a time-limited link that grants temporary access to a specific object in an S3-compatible storage bucket - credentials or bucket permissions required on the recipient's side.
Presigned URLs are useful when you need to:
- Share a file for download without making your bucket public.
- Allow someone to upload a file directly to your bucket without giving them permanent access.
- Grant access that automatically expires after a set period.
Generating a GET Presigned URL (for downloading)
A GET presigned URL lets anyone with the link download a specific object from your bucket.
Option 1 — Using the s3cmd CLI
s3cmd \
--access_key=<access_key> \
--secret_key=<secret_key> \
--host=https://<endpoint_host> \
--host-bucket=https://<bucket_name>.<endpoint_host> \
signurl s3://<bucket_name>/<object_key> <expiration_seconds>Replace the placeholders with your actual values:
| Placeholder | Description |
|---|---|
<access_key> | Your S3 access key |
<secret_key> | Your S3 secret key |
<endpoint_host> | Your S3 endpoint hostname (us-west.s3.qencode.com or eu-central.s3.qencode.com) |
<bucket_name> | Name of your bucket |
<object_key> | Path to the object inside the bucket |
<expiration_seconds> | How long the URL should remain valid (in seconds) |
Option 2 — Using Python (Boto3)
Prerequisite: Install the boto3 module before running the scripts:
pip install boto3Create a settings.py file with your credentials:
S3_ACCESS_KEY = "<access_key>"
S3_SECRET_KEY = "<secret_key>"
REGION_NAME = "<region>" # e.g. "us-west" or "eu-central"
ENDPOINT_URL = "<endpoint>" # e.g. "https://us-west.s3.qencode.com"Then create gen_get_url.py:
import boto3
from botocore.exceptions import ClientError
import settings
def create_presigned_url(bucket_name, object_name, expiration, url_type='get_object'):
s3_client = boto3.client(
's3',
aws_access_key_id=settings.AWS_SERVER_PUBLIC_KEY,
aws_secret_access_key=settings.AWS_SERVER_SECRET_KEY,
region_name=settings.REGION_NAME,
endpoint_url=settings.ENDPOINT_URL
)
try:
response = s3_client.generate_presigned_url(
url_type,
Params={'Bucket': bucket_name, 'Key': object_name},
ExpiresIn=expiration,
)
except ClientError as e:
print(e)
return None
return response
create_presigned_url(
bucket_name='<bucket_name>',
object_name='<object_key>',
expiration=<expiration_seconds>,
url_type='get_object'
)Run it with:
python gen_get_url.pyGenerating a PUT Presigned URL (for uploading)
A PUT presigned URL lets someone upload a file to a specific location in your bucket — without needing your credentials.
Create gen_put_url.py (requires boto3 python module installed as a dependency):
import boto3
from botocore.exceptions import ClientError
import settings
def create_presigned_url(bucket_name, object_name, expiration, url_type='put_object'):
s3_client = boto3.client(
's3',
aws_access_key_id=settings.AWS_SERVER_PUBLIC_KEY,
aws_secret_access_key=settings.AWS_SERVER_SECRET_KEY,
region_name=settings.REGION_NAME,
endpoint_url=settings.ENDPOINT_URL
)
try:
response = s3_client.generate_presigned_url(
url_type,
Params={'Bucket': bucket_name, 'Key': object_name},
ExpiresIn=expiration,
)
except ClientError as e:
print(e)
return None
return response
create_presigned_url(
bucket_name='<bucket_name>',
object_name='<object_key>',
expiration=<expiration_seconds>,
url_type='put_object'
)Run it with:
python gen_put_url.pyUse the same settings.py from the GET example above.
Downloading with a GET Presigned URL
Once you have a GET presigned URL, you can use it to download the object in several ways:
- In a browser — simply paste the URL into the address bar.
- Using curl:
curl -X GET "<presigned_url>"Uploading with a PUT Presigned URL
To upload a local file using a PUT presigned URL:
curl -X PUT -T "/path/to/local/file" "<presigned_url>"Replace /path/to/local/file with the full path to the file on your device.
Key things to know
- A presigned URL can be used multiple times until it expires.
- The expiration time is set when the URL is generated and cannot be changed afterward.
- Anyone who has the URL can use it within the expiration window — treat it like a temporary password and share it only with intended recipients.
For additional information, tutorials, or support, visit the Qencode Documentation page or contact Qencode Support at support@qencode.com.