Add HMAC signature specification to README

Documents the signature scheme: HMAC-SHA256 over host:path:query:width:height:format:expiration
with base64url encoding and Unix timestamp expiration.
This commit is contained in:
2026-01-08 03:35:36 -08:00
parent 30d63e80dc
commit 27eb9fb513

View File

@@ -47,10 +47,59 @@ valid at time of fetch.
# Source Hosts
Source hosts may be whitelisted in the pixa configuration. If not in the
explicit whitelist, a signature using a shared secret must be appended. It
is constructed using HMAC in the following way:
explicit whitelist, a signature using a shared secret must be appended.
FIXME
## Signature Specification
Signatures use HMAC-SHA256 and include an expiration timestamp to prevent replay attacks.
### Signed Data Format
The signature is computed over a colon-separated string:
```
HMAC-SHA256(secret, "host:path:query:width:height:format:expiration")
```
Where:
- `host` - Source origin hostname (e.g., `cdn.example.com`)
- `path` - Source path (e.g., `/photos/cat.jpg`)
- `query` - Source query string, empty string if none
- `width` - Requested width in pixels, `0` for original
- `height` - Requested height in pixels, `0` for original
- `format` - Output format (jpeg, png, webp, avif, gif, orig)
- `expiration` - Unix timestamp when signature expires
### URL Format with Signature
```
/v1/image/<host>/<path>/<size>.<format>?sig=<signature>&exp=<expiration>
```
### Example
For a request to resize `https://cdn.example.com/photos/cat.jpg` to 800x600 WebP
with expiration at Unix timestamp 1704067200:
1. Build the signature input:
```
cdn.example.com:/photos/cat.jpg::800:600:webp:1704067200
```
2. Compute HMAC-SHA256 with your secret key
3. Base64URL-encode the result
4. Final URL:
```
/v1/image/cdn.example.com/photos/cat.jpg/800x600.webp?sig=<base64url>&exp=1704067200
```
### Whitelist Patterns
The whitelist supports two pattern types:
- **Exact match**: `cdn.example.com` - matches only that host
- **Suffix match**: `.example.com` - matches `cdn.example.com`, `images.example.com`, and `example.com`
# configuration