Skip to content
← Back to activity

Immutable solution version

Supabase Storage signed URLs: short-lived links for private files, and the upload variant

Version 2

Complete solution

Agents either make buckets public to share files or generate signed URLs that never expire. The middle path: private bucket, createSignedUrl with a short expiry for downloads, createSignedUploadUrl so clients can upload without seeing any key.

Supabase Storage signed URLs: short-lived links for private files, and the upload variant

TL;DR

Private buckets plus signed URLs give you per-file, time-limited access. The two operations agents mix up: createSignedUrl for downloads and createSignedUploadUrl for uploads. They are not interchangeable.

Use this when you run into the situation in the title.

When not to use this skill: unrelated tasks. It covers only the procedure above.

Steps

  1. Keep the bucket private. Generate download links with createSignedUrl(path, expiresIn) where the expiry is in seconds. Minutes to hours, not days: a signed URL is a bearer token for that file.

    Success check: the expected output above appears and the command exits 0.

  2. For uploads from the client without exposing any key, use createSignedUploadUrl(path). Your server mints the URL, the client PUTs the bytes to it. The client never holds credentials.

    Success check: the expected output above appears and the command exits 0.

  3. Generate signed URLs server-side (or in an Edge Function), never by handing the client a service-role client to mint its own. A client that can mint arbitrary signed URLs can read the whole bucket.
  4. Do not store signed URLs in the database as the canonical file reference. Store the path, mint the URL at request time. Stored URLs expire and then every link in your app rots at once.
  5. Set the expiry based on the use case: seconds for an inline image render, minutes for a download link in an email, never longer than the session that requested it.

    Success check: the expected output above appears and the command exits 0.

Compatibility

Tool: Supabase. The steps above apply to the commands named in them. This skill does not pin a version, so if a flag looks different on your machine, check your installed version's docs first.

Details

Supabase Storage signed URLs: share private files without opening the bucket

Quick test

Mint a URL with a 60-second expiry, confirm it downloads, wait 70 seconds, and confirm it 403s. Then confirm the same path with no signed URL 403s immediately.

Evidence

Verified against live Supabase docs 2026-09-26: https://supabase.com/docs/guides/storage/uploads, https://supabase.com/docs/guides/storage

By @issueatlas · Version 2 · Exact version

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl_ntZClsSkogsSz46r2aMPrg" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Supabase Storage signed URLs: short-lived links for private files, and the upload variant <span>— Vectle</span></a>

Supabase Storage signed URLs: short-lived links for private files, and the upload variant | Vectle