> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackshift.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Private assets and signed URLs

> Keep files private by default and generate short-lived URLs only when a user should download them.

<Tip>
  **Live.** This area is documented as current, user-reliable behavior.
</Tip>

## Goal

Serve private files without making them publicly cacheable.

## Prerequisites

* An uploaded private asset

## Workflow

<Steps>
  <Step>
    Upload the file with visibility private.
  </Step>

  <Step>
    Store the returned asset ID in your database.
  </Step>

  <Step>
    Generate a signed URL when an authorized user needs access.
  </Step>

  <Step>
    Use maxDownloads for one-time downloads when appropriate.
  </Step>
</Steps>

## Create a signed download URL

```ts theme={null}
const signed = await stackshift.assets.signedUrl(asset.id, {
  expiresIn: '10m',
  maxDownloads: 1,
})

return signed.url
```

## How signing protects the file

* Private assets have no public URL — they are only reachable through a signed link your server mints.
* expiresIn keeps links short-lived so a leaked URL stops working quickly.
* maxDownloads caps how many times a single link can be used, which suits one-time downloads.
* Responses come back with no-store cache headers so private files are not cached by intermediaries.

## Where signing belongs

Always mint signed URLs on the server, where the API key lives, and hand only the resulting URL to the browser. Never expose the API key to the client just to generate a link.

## Expected result

<Check>
  Private assets are only downloadable with valid signed URLs and are returned with no-store cache headers.
</Check>

## Related guides

<CardGroup cols={2}>
  <Card title="StackShift Assets overview" href="/assets/overview">
    StackShift Assets is now a live media platform: storage, CDN delivery, image optimization, upload sessions, DAM, video, scanning, governance, AI metadata, and version history.
  </Card>

  <Card title="Direct browser uploads" href="/assets/direct-browser-uploads">
    Create a short-lived signed upload URL on your server, then PUT the file directly from the browser.
  </Card>

  <Card title="Video, scanning, and governance" href="/assets/video-scanning-and-governance">
    Process video asynchronously, deliver HLS and posters, scan uploads, quarantine infected assets, and enforce account policies.
  </Card>
</CardGroup>
