VibeSecurity

Data and privacy

What is Signed URL?

A signed URL, also called a presigned URL, is a link to a private file that includes a cryptographic signature and an expiry time, giving whoever holds the link temporary access without needing to log in.

Private buckets refuse anonymous requests, which is what you want. But your app still needs to show a user their own invoice or let them download an export. A signed URL solves this: your server, which holds the credentials, asks the storage service to create a link for one specific file that works for a limited time. The browser can then fetch the file directly.

A signed URL is a bearer credential. Anyone who obtains the link can use it until it expires, and the storage service does not check who they are. Problems appear when generated code sets very long expiry times to avoid handling refreshes, stores signed links in the database as if they were permanent, or exposes an endpoint that will sign a URL for any file path the caller asks for without checking that the file belongs to them.

Create signed URLs on the server, only after confirming that the logged-in user is allowed to see that file. Keep the lifetime short, generate a fresh link each time it is needed and avoid logging or emailing the links. The same applies to signed upload URLs: limit them to a single path and a short window.

Supabase: a link that expires after 60 seconds
const { data, error } = await supabase.storage
  .from("documents")
  .createSignedUrl(`${user.id}/invoice.pdf`, 60);

Related terms

Sources

  1. 1.Supabase Docs: createSignedUrl
  2. 2.AWS Docs: Sharing objects with presigned URLs
  3. 3.Cloudflare R2 Docs: Presigned URLs