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.
- Save a Qencode transcoding output directly to a specific storage object without including storage credentials in the transcoding task.
- Grant access that automatically expires after a set period.
There are two main types of presigned URLs:
- GET presigned URL - provides temporary access to download an object.
- PUT presigned URL - provides temporary access to upload or replace an object.
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.
Saving Qencode transcoding output to a presigned S3 URL
Qencode can save a transcoding output directly to a presigned S3 PUT URL. This allows Qencode to upload the result without including the storage access key or secret key in the transcoding task.
Add the complete presigned HTTPS PUT URL to destination:
{
"destination":
{
"url": "https://nyc3.digitaloceanspaces.com/yourspace/output.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Signature=..."
}
}The storage destination type is detected automatically when:
- The URL uses the http:// or https:// scheme.
- The URL contains the X-Amz-Signature query parameter.
No additional storage type or destination field is required.
The key and secret are no longer required for pre-signed S3 upload. They can now be omitted entirely, and they are ignored either way (whether provided or not) — they do not affect the upload. No dummy values are needed anymore.
Destination parameters
destination - object or array of objects
| Name | Type | Requirement | Description |
|---|---|---|---|
| url | string | Required | The URL (including the protocol) of the output to be created |
| key | string | not Required* | S3 storage Access Key ID |
| secret | string | not Required* | S3 storage Secret Access Key |
| permissions | string | Optional | S3 object access permissions |
| acl | string | Optional | Define the Access Control List (ACL) for an object when saving transcoding results to Amazon S3 |
| storage_class | string | Optional | S3 storage class (AWS) |
| cache_control | string | Optional | Sets the Cache-Control metadata for S3 storage |
| is_passive | integer (1 or 0) | Optional | Enables FTP passive mode |
| use_tls | integer (1 or 0) | Optional | Enables FTP over SSL (TLS) |
| tcp_port | integer | Optional | TCP port for Aspera |
| udp_port | integer | Optional | UDP port for Aspera |
- key and secret are required for regular S3 destinations (s3://), but are optional and ignored for pre-signed S3 PUT URLs.
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.