Osy#the first language built for agents
Agents firstAgentic appsWorkflowsDurable Execution — built inSecurityTestingThe editorThe UI modelOne program

Reference / Storage

File.SignedUrl

string File.SignedUrl(string path) // under `using Osyrin.Storage;`

Mints a temporary, signed URL that lets an authorized browser fetch a PRIVATE app file — one stored outside `public/` — without carrying a login token. `File.Url` serves only public files; `File.SignedUrl` is how a private report, invoice, or per-user image reaches the browser. The link expires on its own after a few minutes.

preview2 examples compiled by CIstoragefilessecurityui

Summary#

File.SignedUrl(path) returns a URL a browser can use to fetch a private app file — a file stored under any path other than public/. The URL carries a short-lived, cryptographically signed token, so it works for anyone who holds the link until it expires, and 404s otherwise. Use it for a per-user report, an invoice PDF, or a private image:

string url = File.SignedUrl("reports/" + user.Id + "/q3.pdf");

Like the rest of the File.* surface it is gated on using Osyrin.Storage;.

Signature#

using Osyrin.Storage;

string File.SignedUrl(string path)

Description#

The app-file serving route treats public/ and everything else very differently. A file under public/ is served to anyone, anonymously, and its URL is just File.Url. A file under any other path is private: the serving route refuses it outright — until the request carries a valid signed token. File.SignedUrl mints that token.

Can I put it straight in a render argument?#

This is the key difference from File.Url. File.Url is pure string formatting, so it can sit directly in a render argument (Image(src: File.Url(...))) and be built by the browser. File.SignedUrl signs with your app's key, which the browser never holds — so it runs on the server, inside a function or action. Call it where you have the path in hand (an action that prepares a download, a function that returns a link) and hand the result to the UI.

Who can use the link, and for how long?#

A signed URL is a bearer link: whoever holds it can fetch that one file until it expires. That is exactly what lets a browser <img> or a download load without a login header. Two properties keep it safe:

  • It expires. The link is valid for a short window (currently 15 minutes), then stops working. Mint it when the page or download is requested, not far in advance.
  • It unlocks exactly one file, for one app. The path and your application are sealed inside the token, so a link minted for reports/a.pdf cannot be edited to fetch reports/b.pdf, and a link from one app is meaningless on another. A tampered or expired link simply 404s — a private file's existence is never revealed to someone without a valid link.

You never see, choose, or store a key — the platform mints, protects, and rotates it, exactly as for Crypto.Encrypt and Crypto.Decrypt.

File.SignedUrl is signing, not a storage read: it does not check that the file exists (a missing file 404s when the browser follows the link), and it is not available inside a query.

Examples#

An action returns a private, expiring download link for the caller's own report:

using Osyrin.Storage;

[Principal] entity User { [MaxLength(200)] string Email; }

// The report was written earlier under a NON-public path, so it is not servable anonymously.
string ReportDownloadUrl(User user) {
  return File.SignedUrl("reports/" + user.Id + "/q3.pdf");
}

Writing a private file, then handing back a link to it:

using Osyrin.Storage;

string SaveAndLinkInvoice(string invoiceId, byte[] pdf) {
  var path = "invoices/" + invoiceId + ".pdf";   // NOT under public/ — private by default
  File.WriteAllBytes(path, pdf);
  return File.SignedUrl(path);                    // a temporary link the browser can open
}

See also#

Related

File.Url

Turns an app-relative file path into the public URL a browser can fetch it from — `File.Url("public/x.png")` returns…

Crypto.Encrypt and Crypto.Decrypt

Encrypt and decrypt values under your app's key, which the platform mints, protects, and rotates for you. There is no…