Signed URLs (Delivery)
Generate time-limited signed URLs for protected file access.
Signed URLs provide temporary access to files with private or authenticated access types. They contain an expiration timestamp and HMAC-SHA256 signature.
Generating a Signed URL
Request a signed delivery URL through the API:
curl -X POST https://api.tzzl.io/api/v1/files/FILE_ID/signed-url \
-H "Authorization: Bearer sk_a1b2c3d4..."
Response
The signed URL includes expires and signature parameters:
https://cdn.tzzl.io/a1b2c3/image-01HQ...?expires=1700000000&signature=abc123...
URL Structure
{cdn_url}/{space_handle}/{storage_path}?expires={unix_timestamp}&signature={hmac_hex}
| Parameter | Description |
|---|---|
expires | Unix timestamp when the URL becomes invalid |
signature | HMAC-SHA256 hex digest of the URL path and sorted query params |
How Validation Works
The CDN validates signed URLs by:
- Checking that both
signatureandexpiresparameters are present - Verifying the URL has not expired (
expires> current time) - Reconstructing the string to sign from the URL path and sorted parameters (excluding the signature itself)
- Computing the expected HMAC-SHA256 signature
- Comparing the provided signature to the expected one
If validation fails, the CDN returns a 403 error.
Adding Transformations
You can combine signed URLs with transformation parameters. The transformation parameters are included in the signature calculation:
https://cdn.tzzl.io/a1b2c3/image-01HQ...?w=400&f=webp&expires=1700000000&signature=abc123...
The signature covers all query parameters. You cannot add or modify transformation parameters after the URL is signed.
Access Types
| File Type | Signed URL Required? |
|---|---|
upload | No (publicly accessible) |
private | Yes, for URL generation. Delivery is public after signing. |
authenticated | Yes, for all access. No CDN caching. |
Expiration
The default expiration is 1 hour (3600 seconds). After expiration, the URL returns a 403 error and a new signed URL must be generated.
Security
- Signed URLs use HMAC-SHA256 with a server-side secret
- The signature covers the full URL path and all query parameters
- Expired URLs are always rejected, even if the signature is valid
- Tampering with any parameter invalidates the signature