Skip to main content

HMAC Signing

HMAC signing lets you restrict PreviewProxy so that only requests generated by your application are accepted. When enabled, every request must include a valid sig parameter or it will be rejected with a 403.

Enabling HMAC signing

Set the HMAC_KEY environment variable to a secret string:

HMAC_KEY=mysecret
warning

If HMAC_KEY is not set, all requests are accepted without authentication. Always set HMAC_KEY in production.

Algorithm

Signatures are computed using HMAC-SHA256, encoded as URL-safe base64 with no padding (also known as base64url).

Canonical message format

The message that is signed is constructed as follows:

<params_string>:<image_url>

Where:

  • params_string - all query parameters except sig, sorted alphabetically by key, joined with & in key=value format
  • image_url - the full source image URL, decoded (not percent-encoded)

The sig parameter is appended to the final request URL but is excluded from the canonical string used for signing.

Example

Given the following inputs:

FieldValue
Paramsw=400&format=webp
Image URLhttps://example.com/photo.jpg
HMAC keymysecret

Step 1 - Sort params alphabetically:

format=webp&w=400

Step 2 - Build the canonical message:

format=webp&w=400:https://example.com/photo.jpg

Step 3 - Compute the signature:

sig = HMAC-SHA256("mysecret", "format=webp&w=400:https://example.com/photo.jpg")
= <base64url-encoded result>

Step 4 - Append sig to the request URL:

/w=400,format=webp,sig=<base64sig>/https://example.com/photo.jpg

Signing example in Node.js

const crypto = require('crypto');

function sign(key, params, imageUrl) {
const sorted = Object.entries(params)
.sort(([a], [b]) => a.localeCompare(b))
.map(([k, v]) => `${k}=${v}`)
.join('&');
const message = `${sorted}:${imageUrl}`;
return crypto.createHmac('sha256', key)
.update(message)
.digest('base64url');
}

// Usage
const sig = sign('mysecret', { w: '400', format: 'webp' }, 'https://example.com/photo.jpg');
console.log(sig);
// Append to request: /w=400,format=webp,sig=<sig>/https://example.com/photo.jpg

Key rotation

There is no built-in key rotation mechanism. To rotate your HMAC_KEY, update the environment variable and redeploy. Any pre-generated URLs signed with the old key will become invalid and must be re-signed.