Object Storage & Blob Storage • Presigned URLs & Access ControlEasy⏱️ ~3 min
What Are Presigned URLs and When Do You Use Them?
Presigned URLs are time bounded, cryptographically signed URLs that grant temporary access to perform a specific operation on a specific object in storage without requiring the caller to hold permanent credentials. Think of them as capability tokens embedded directly in the URL: the signature, expiration timestamp, method constraint, and resource path are all encoded in the query parameters, allowing the storage system to verify the request independently.
The core value proposition is offloading heavy data transfer from your application servers. Instead of clients uploading a 5 MB photo through your backend (consuming server bandwidth twice: client to server, server to storage), your app generates a presigned PUT URL in milliseconds, and the client uploads directly to object storage. Your application only handles kilobytes for URL generation, while the storage layer handles gigabytes of actual data transfer.
Presigned URLs shine in two primary patterns. First, direct to storage writes where end users upload content (photos, videos, documents) without your servers becoming a bottleneck. Second, temporary reads for private content where you need to serve downloads without granting permanent access or storing credentials client side. Amazon S3, Google Cloud Storage, and Azure Blob Storage all support this pattern with similar mechanics but different implementation details.
The authorization model is critical to understand: your application remains the control plane, authenticating users and applying business logic (ownership checks, quota enforcement, file type validation). The presigned URL you generate becomes a bearer token that the storage system honors as the data plane. Once issued, anyone with that URL can use it until expiration, typically 1 to 5 minutes for uploads and seconds to hours for downloads depending on your security requirements.
💡 Key Takeaways
•Bearer token security model: Anyone with the URL can use it until expiration. Keep Time To Live (TTL) short (1 to 5 minutes for uploads, seconds to minutes for downloads) and scope tightly to specific object keys and HTTP methods.
•Massive bandwidth savings: For an app with 2 million photo uploads per day at 3 MB average, direct to storage eliminates approximately 6 TB per day of server egress. At typical Network Address Translation (NAT) charges around $0.045 per GB, this saves roughly $270 daily plus reduced CPU and autoscaling costs.
•Control plane versus data plane separation: Your application authenticates users, enforces business rules, and issues URLs (control plane, handling kilobytes). Storage handles actual bytes transfer (data plane, handling gigabytes), allowing independent horizontal scaling of each layer.
•Limited revocation capability: Once issued, individual presigned URLs typically cannot be revoked. Your options are rotating signing keys (affects all URLs) or changing object Access Control List (ACL) policies (coarse grained). Mitigation strategy is very short TTLs combined with tight scoping to specific prefixes and methods.
📌 Examples
Social media app: User taps upload button. App calls POST /api/photos/upload-url with auth token. Backend validates user, generates S3 presigned PUT URL valid for 3 minutes targeting user-123/photos/uuid.jpg, returns URL. Client PUT directly to S3 with photo bytes. Backend receives S3 event notification, validates upload, creates database record.
Video platform: User requests private video. App validates subscription status, generates presigned GET URL for video-bucket/user-456/video.mp4 valid for 60 seconds. Client player fetches video directly from storage using the URL. No permanent credentials stored on client device.
Partner integration: External system needs to upload reports to your bucket. Instead of sharing long lived credentials, your API generates presigned URLs scoped to partner-uploads/partner-id/ prefix with 5 minute expiration and Content-Length header constraint to prevent abuse.