Presigned URL

On this page 7

A presigned URL is a web address for one object in cloud storage that carries a cryptographic signature and an expiration time, so anyone holding it can perform one specific operation, such as downloading or uploading that object, without having their own credentials. In cloud storage, presigned URLs are the standard way to grant temporary, narrowly scoped access to private objects.

The address is generated by a party that already has permission, typically a backend service. The storage service later verifies the signature on every request, which means the bucket can stay private while selected objects are shared for minutes or hours.

How a presigned URL is generated and verified

A presigned URL is created locally, without a call to the storage service. The signing code combines the HTTP method, the bucket and object key, selected headers, the expiration and the identity of the signer into a canonical request, and then computes an HMAC signature with the signer’s secret key. In S3 and compatible object storage, this follows Signature Version 4.

The result is appended to the address as query parameters, for example X-Amz-Expires and X-Amz-Signature. When the request arrives, the service recomputes the signature, checks that the time window is still open and then evaluates the signer’s current permissions. A presigned URL therefore never grants more than its creator could do at the moment of use.

Because the signature covers the method and the object key, a link signed for a download cannot be reused for an upload or for another object. Changing any signed component invalidates the signature.

Operations, parameters and limits

A presigned URL is defined by a small set of parameters, and each one narrows what the holder can do. The table lists the parameters that matter most in practice.

ParameterTypical valuesEffect
HTTP methodGET, PUT, HEAD, DELETEDefines the single permitted operation
Object keyOne exact path in the bucketLimits access to one object
ExpirationSeconds up to 7 days for S3 Signature Version 4Defines the access window
Signed headersContent type, checksum, encryption settingsForces the client to send matching values
Signer identityUser, role or temporary credentialsCaps permissions and can shorten validity
Main parameters of a presigned URL

The signer identity has a practical effect that surprises many teams. When the signer uses temporary role credentials, the presigned URL stops working when those credentials expire, even if the requested expiration was longer. Revoking the signer’s permissions also invalidates every outstanding URL it created.

Large uploads use multipart upload, where the backend presigns each part separately, often in pieces of 5 MiB or more. For browser uploads that need size limits or key prefixes, a presigned POST with a policy document is often a better fit than a presigned PUT.

Presigned URL compared with other access methods

A presigned URL is only one of several ways to expose objects in a storage bucket. The right choice depends on who needs access, for how long and at what scale.

MethodScopeBest suited for
Presigned URLOne object, one operation, limited timePer-user downloads and direct uploads
Public bucket or objectEveryone, indefinitelyTruly public static assets
Bucket policy or roleIdentities inside the organizationService-to-service access
CDN signed URL or cookieContent behind a content delivery networkPaid media and high-volume delivery
Proxy through the applicationWhatever the application allowsSmall files that need inspection or transformation

Compared with proxying downloads through the application, a presigned URL moves the data path directly between the client and the storage service. This removes bandwidth and memory pressure from application servers and is the main reason the pattern is popular for files of hundreds of megabytes or more.

Choosing expiration and scope

The guiding rule is to keep the access window as short as the use case allows. A presigned URL is a bearer token: whoever obtains it can use it, so its lifetime is effectively the exposure window if it leaks.

Use caseSuggested expirationReason
Browser download after a click1-15 minutesThe client uses it immediately
Direct upload from a web form5-60 minutesCovers slow connections and large files
Link sent by emailHours to a few daysThe recipient opens it later
Partner batch transferUp to the maximum allowedBetter replaced by role-based access if recurring
Decision table for presigned URL settings

Upload URLs should sign the content type and, where supported, a checksum, so the client cannot store an unexpected file type. The backend should also choose the object key itself, typically with a random identifier, instead of accepting a file name from the client.

Security risks and common mistakes

Most problems with presigned URLs come from treating them as harmless links. They are credentials in disguise and travel through places where credentials should not be stored.

  • Leakage through logs, browser history, analytics tools or referrer headers exposes valid URLs.
  • Long expirations by default turn a short-term share into a semi-permanent public link.
  • Signing with long-term keys prevents fast revocation; short-lived role credentials are safer.
  • Unvalidated uploads allow oversized or malicious files to land in the bucket.
  • Clock skew on the signing host makes freshly created URLs fail or expire early.
  • Missing CORS configuration on the bucket blocks browser uploads that are otherwise correct.

A presigned URL cannot be revoked individually. If one leaks, the options are to wait for expiration, remove the signer’s permissions or delete or move the object, which is why short lifetimes are the primary control.

In simple terms

Think of a hotel key card that opens only one room and stops working at checkout time. The hotel does not give out its master key; it hands over a card limited to one door and one period.

A presigned URL works the same way for files stored online. A service creates a special link that opens exactly one file for a short time. Whoever has the link can use it, so it should be shared carefully and expire quickly.

A practical example

A video editing platform lets customers upload raw footage files of 2 to 20 GB. Sending such files through the application servers would overload them, so the backend instead creates a multipart upload and returns presigned PUT URLs for each 100 MiB part, each valid for 60 minutes.

The browser uploads the parts directly to object storage, and the backend completes the upload when all parts arrive. For downloads, finished videos get presigned GET URLs valid for 10 minutes, generated each time a logged-in user clicks the download button. The result is that application servers handle only small signing requests, while the storage service carries all heavy traffic and the bucket stays private.