Signed URLs

Introduction

If you don't want to make your files publicly accessible, you can use Access Rules to restrict access.

You can then use signed URLs to grant temporary access to those private files.

For example, you might use signed URLs to serve images in a private dashboard, or to allow a user to download a file they have purchased.


How it works

A signed delivery URL includes a valid signature which will grant access to a private file for a limited time.

A signed URL looks like this:

<img src="https://you.ittybit.net/private/image.png?expiry=1765432100&method=get&signature=1234abcd5678efgh9012" />

Once you have the signed URL, you can use it to make a GET request to view the file. For example, you could use it as the src for an <img> tag, or fetch it directly in your application.


Generate signatures

If you have access to a server-side environment, you can generate signatures yourself.

import crypto from 'crypto';

const DOMAIN = 'you.ittybit.net';
const ITTYBIT_API_KEY = process.env.ITTYBIT_API_KEY;

function generateSignature({ string }) {
  const hmac = crypto.createHmac('sha256', ITTYBIT_API_KEY);
  hmac.update(string);
  const base64 = hmac.digest('base64url');
  return base64;
}

async function createSignedUrl({ path }) {
  try {
    const expiry = Math.floor(Date.now() / 1000) + 60 * 60; // 1 hour from now
    const string = `${path}?expiry=${expiry}&method=get`;
    const signature = generateSignature({ string });
    const signedUrl = `https://${DOMAIN}/${string}&signature=${signature}`;
    return { signedUrl };
  } catch (error) {
    // handle the error
  }
}

// Example usage
const { signedUrl } = await createSignedUrl({ path: 'private/image.png' });
// Outputs: https://you.ittybit.net/private/image.png?expiry=1735689600&method=get&signature=a1b2c3d4e5f6...

A JS/node backend example is given above. More language examples are coming soon but please contact us and we'd be happy to help you write something that fits into your stack.


Using signed URLs

Once you have the signed URL, you can use it to access the file.

For images, you can use the signedUrl directly in an <img> tag.

<img src={signedUrl} alt="A private image that only cool people can see" />

The response to a GET request on a signed URL is the file itself, not a JSON object.


Downloading files

You can download a file by creating a link with the signedUrl as the href.

<a href={signedUrl} download="purchased-movie.mp4">Download file</a>

Common Pitfalls

The file will only be accessible for the duration of the signed URL.

Because signed URLs are only designed for short-term access, they include an expiry timestamp.

This means you should not generate signed URLs as part of a build process, because they may stop working before the next build is deployed.

TLDR; If you need signed URLs inside a JS framework site (Next.js, SvelteKit, etc) then you should use server actions to generate them at runtime.

On this page