On this page

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:

PlaceholderDescription
<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 boto3

Create 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.py

Generating 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.

note
Note
If an object already exists at the specified key, it will be replaced by the uploaded file.

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.py

Use 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 pageLink or contact Qencode Support at support@qencode.com.