Back

Blog details

Generating Presigned URLs on AIOZ Storage with Python

AIOZ Network
5 min readAugust 09, 2026
aioz-storage
Generating Presigned URLs on AIOZ Storage with Python

A presigned URL lets someone upload or download a specific object on AIOZ Storage without ever holding your credentials, a temporary, scoped link instead of a shared access grant. Generating one against AIOZ Storage takes exactly one boto3 method, generate_presigned_url, plus the same endpoint configuration every other AIOZ Storage Python script needs. This guide covers both directions, download links and upload links, and the one detail that actually matters: how long the link stays valid.

TL;DR:

  • generate_presigned_url('get_object', ...) creates a temporary download link; the same method with 'put_object' creates a temporary upload link.
  • Presigned URLs work against AIOZ Storage exactly like they work against S3, since signing happens client-side and doesn't depend on anything AIOZ-specific beyond the endpoint config.
  • The ExpiresIn parameter controls how long the link works, in seconds, and there is no way to revoke a presigned URL early once it's been handed out.

Do Presigned URLs Work on AIOZ Storage the Same Way They Work on S3?

Yes, without any AIOZ-specific workaround. Presigned URL generation is a client-side signing operation, boto3 computes a cryptographic signature using your credentials and embeds it in the URL, and the receiving server just validates that signature against the request. Since AIOZ Storage speaks the same S3-compatible API, that validation works identically to Amazon S3, provided your boto3 client is configured with AIOZ Storage's endpoint and addressing_style: path, the same setup every other AIOZ Storage Python script in this series uses.

Setting Up the Client

import boto3
from botocore.config import Config

s3_client = boto3.client(
    "s3",
    region_name="us-east-1",
    endpoint_url="https://s3.aiozstorage.network",
    aws_access_key_id="<your-aioz-storage-access-key-id>",
    aws_secret_access_key="<your-aioz-storage-secret-access-key>",
    config=Config(s3={"addressing_style": "path"}),
)

This is the same client configuration AIOZ's own SDK documentation specifies, and it's the only setup step presigned URLs need beyond a valid access grant.

Generating a Presigned Download URL

url = s3_client.generate_presigned_url(
    "get_object",
    Params={"Bucket": "your-bucket", "Key": "your-object-key"},
    ExpiresIn=3600,
)
print(url)

That URL works in a browser or any HTTP client for the next hour (3600 seconds), no AIOZ Storage credentials required on the requesting end. Anyone with the link can download that specific object until it expires, and nothing else in the bucket.

Laptop screen displaying colorful lines of source code

Generating a Presigned Upload URL

url = s3_client.generate_presigned_url(
    "put_object",
    Params={"Bucket": "your-bucket", "Key": "new-object-key"},
    ExpiresIn=3600,
)

The difference is the operation name, put_object instead of get_object, and what the URL is good for: a client can PUT a file directly to that URL and it lands in your bucket at the key you specified, without ever touching your application server or holding your AIOZ Storage credentials. This is the pattern behind most "upload directly from the browser" flows, your backend generates the URL, the browser does the actual upload.

The Real Gotcha: Content-Type Must Match Exactly

If you include ContentType when generating an upload URL, the client's actual PUT request has to send that exact same Content-Type header, or the request fails with SignatureDoesNotMatch. That's not an AIOZ Storage quirk, it's how S3-style request signing works generally: any parameter included when the URL was signed becomes part of what the receiving server checks against, and a mismatch anywhere breaks the signature.

url = s3_client.generate_presigned_url(
    "put_object",
    Params={"Bucket": "your-bucket", "Key": "photo.jpg", "ContentType": "image/jpeg"},
    ExpiresIn=900,
)

Whoever uses that URL needs to send Content-Type: image/jpeg on the actual PUT request, not image/jpg, not left blank, not anything else. If you don't need to constrain the content type, leave ContentType out of Params entirely rather than setting it to something generic, since an included-but-wrong value fails, while an omitted value just doesn't get checked.

Laptop displaying a code editor with dark theme and syntax highlighting

How Long Should ExpiresIn Actually Be?

Shorter than feels convenient, as a default. ExpiresIn is in seconds, and there's no method to revoke a presigned URL once it's been generated, waiting it out is the only way it stops working. A download link handed to a user for an immediate action (viewing a file, downloading a report) can reasonably use a short window, 300 to 900 seconds. An upload URL generated for a client-side upload flow that might take a while on a slow connection needs enough headroom to actually finish, but there's an outer limit either way: AWS documents a 7-day (604800 seconds) maximum for presigned URLs generated with long-term credentials (stated directly for the AWS CLI's presign command, and the same SigV4 signing process boto3 uses underneath), a ceiling AIOZ Storage's S3-compatible API inherits since presigned URL expiry is enforced by the signature itself, not a server-side setting. Don't default to the maximum just because it's available, scope the expiry to how long the link actually needs to work.

Frequently Asked Questions

What boto3 method generates a presigned URL for AIOZ Storage?
generate_presigned_url, with 'get_object' for a download link or 'put_object' for an upload link, called on a boto3 S3 client configured with AIOZ Storage's endpoint.

Do presigned URLs require any AIOZ-specific configuration?
No beyond the standard AIOZ Storage boto3 client setup, endpoint_url and addressing_style: path. Signing itself is a client-side operation with no server round trip.

Can I revoke a presigned URL before it expires?
No. There's no API call to invalidate a presigned URL early. If you need that control, use a shorter ExpiresIn value in the first place rather than relying on being able to cancel it later.

What's the maximum expiration time for a presigned URL?
7 days (604800 seconds) with long-term credentials, per AWS's documentation for the underlying SigV4 signing process, a limit AIOZ Storage's S3-compatible API inherits since expiry is enforced through the signature, not a server-side policy.

Can someone use a presigned upload URL to overwrite a different file?
No. The URL is signed for a specific bucket and key combination. It can't be used to write to a different object than the one it was generated for.

Why does my presigned upload URL fail with SignatureDoesNotMatch?
Usually a Content-Type mismatch. If you included ContentType when generating the URL, the client's actual PUT request must send that exact same header value, or the signature check fails.

Is a presigned URL the same thing as an access grant?
No. An access grant is a broader, AIOZ Storage-specific credential covering multiple actions and objects. A presigned URL is scoped to exactly one operation on exactly one object, generated by a client already holding valid credentials.

References

We only send updates when meaningful changes ship, and you can unsubscribe anytime

Related Content

blog thumbnail

What AI Agent Sandboxes on Modal and E2B Actually Store

AI agent sandboxes need external storage for files that outlive the sandbox. Real providers like Modal and E2B mount S3-compatible buckets, AIOZ Storage included.

aioz-storage
6 min readAugust 22, 2026
blog thumbnail

Offloading LangGraph Agent Checkpoints to AIOZ Storage

AIOZ storage can back LangGraph's S3 checkpoint offload tier, but not the whole backend. Here is the real DynamoDB-plus-S3 setup and its credential gap.

aioz-storage
6 min readAugust 21, 2026
blog thumbnail

AIOZ Storage as a Dataset and Model-Output Backend

AIOZ storage for AI datasets means S3-compatible buckets for training data and model outputs, no native versioning or lifecycle policies. Here is the honest scope.

aioz-storage
6 min readAugust 20, 2026
blog thumbnail

AIOZ Storage for AI and Data Pipelines: What's Real

AIOZ storage for AI workloads means S3-compatible object storage for datasets, checkpoints, and model outputs. No vector database. Here is what is real.

aioz-storage
6 min readAugust 19, 2026
blog thumbnail

Managing Team Access and Sub-Users on AIOZ Storage

Add AIOZ storage team members through the dashboard's 3-step wizard: name and password, per-bucket permissions, and a one-time credential download.

aioz-storage
6 min readAugust 18, 2026
blog thumbnail

Calling AIOZ Storage's S3 API Directly with Postman

No Postman collection to import. AIOZ Storage docs show building raw S3 requests by hand, authenticated with AWS Signature and your access grant keys.

aioz-storage
4 min readAugust 17, 2026