> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.ibee.co.in/docs/infrastructure/object-storage/objects/presigned-urls/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ibee.co.in/_mcp/server. # Presigned URLs > Generate time-limited URLs for uploading or downloading IBEE Object Storage objects without sharing your credentials. A **presigned URL** is a regular HTTPS URL with an embedded signature that grants temporary access to a single object — no Access Key required by the recipient. Use presigned URLs to: * Let a user **download** a private object from a browser, without giving them credentials. * Let a client **upload** a file directly to your bucket, bypassing your backend. * Hand a third-party system temporary access to a single file. The URL stops working when its expiry passes. ## Before you begin * A bucket ([Create a bucket](/docs/infrastructure/object-storage/buckets)) * An [API credential](/docs/infrastructure/object-storage/api-tokens) with at least **Object Read & Write** scope on the target bucket — used to sign URLs The S3 endpoint for the bucket's workspace is `https://{workspaceId}.blob.ibeestorage.com`. ## Generate a download URL with the AWS CLI ```bash aws --endpoint-url https://{workspaceId}.blob.ibeestorage.com \ --profile ibee \ s3 presign s3://my-bucket/reports/2026-05.pdf \ --expires-in 3600 ``` The command prints a URL with embedded signature parameters: ```text https://{workspaceId}.blob.ibeestorage.com/my-bucket/reports/2026-05.pdf? X-Amz-Algorithm=AWS4-HMAC-SHA256 &X-Amz-Credential=... &X-Amz-Date=... &X-Amz-Expires=3600 &X-Amz-SignedHeaders=host &X-Amz-Signature=... ``` Anyone with the URL can `GET` the object until the expiry passes. ## Generate from an SDK **`Python (boto3)`** ```python title="Python (boto3)" from datetime import timedelta import boto3 s3 = boto3.client( "s3", endpoint_url="https://{workspaceId}.blob.ibeestorage.com", aws_access_key_id="AKIA...", aws_secret_access_key="", ) url = s3.generate_presigned_url( "get_object", Params={"Bucket": "my-bucket", "Key": "reports/2026-05.pdf"}, ExpiresIn=int(timedelta(hours=1).total_seconds()), ) print(url) ``` **`Node.js (AWS SDK v3)`** ```javascript title="Node.js (AWS SDK v3)" import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3"; import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; const s3 = new S3Client({ endpoint: "https://{workspaceId}.blob.ibeestorage.com", credentials: { accessKeyId, secretAccessKey }, }); const url = await getSignedUrl( s3, new GetObjectCommand({ Bucket: "my-bucket", Key: "reports/2026-05.pdf" }), { expiresIn: 3600 } ); console.log(url); ``` ## Presigned uploads (`PUT`) Generate a URL the client can `PUT` to directly: ```python url = s3.generate_presigned_url( "put_object", Params={ "Bucket": "my-bucket", "Key": "uploads/avatar.png", "ContentType": "image/png", }, ExpiresIn=600, ) ``` The client uploads with a single HTTP request: ```bash curl -X PUT "$URL" \ -H "Content-Type: image/png" \ --data-binary @avatar.png ``` ## Presigned `POST` (browser uploads with form data) `POST` policies are the right fit for browser-based form uploads — they let you constrain the upload (key prefix, max size, content type) before the file is sent. ```python post = s3.generate_presigned_post( Bucket="my-bucket", Key="uploads/${filename}", Conditions=[ ["content-length-range", 0, 10 * 1024 * 1024], # 10 MB max ["starts-with", "$Content-Type", "image/"], ], ExpiresIn=600, ) print(post) # url + fields ``` ## Best practices * **Use the shortest expiry that works.** Don't issue a long-lived URL when 5 minutes is enough. * **Bind to content type and size** for upload URLs to prevent abuse. * **Don't log presigned URLs** — anyone who reads the log gets the same access. * **Treat them as one-time secrets** — regenerate per request rather than caching. ## Limitations * The URL stops working if the API token used to sign it is revoked. * Each presigned URL is valid for **one HTTP method on one key**. Different operations need different URLs. ## Related * [Objects](/docs/infrastructure/object-storage/objects) * [API Credentials](/docs/infrastructure/object-storage/api-tokens) * [Bucket policies](/docs/infrastructure/object-storage/buckets/bucket-policies) * [CORS](/docs/infrastructure/object-storage/buckets/cors) > Generate time-limited URLs for uploading or downloading IBEE Object Storage objects without sharing your credentials.