Request Signing
Sign client requests and verify signatures server-side with nonce replay protection.
Request signing adds an HMAC integrity/authentication layer to storage API calls.
Main exports:
createClientRequestSignercreateVerifySignatureMiddlewarecreateRequestSignercreateInMemoryNonceStoregenerateNonce
Server Verification
Use createVerifySignatureMiddleware in createStorage middleware chain:
createVerifySignatureMiddleware({
secret: process.env.SIGNING_SECRET!,
timestampToleranceMs: 300_000,
requireNonce: true,
nonceStore: createInMemoryNonceStore(),
});Verified requests add this to middleware context:
{
signature: {
verified: true,
timestamp: number,
nonce?: string
}
}Client Signing
Use createClientRequestSigner to produce signing headers:
const signer = createClientRequestSigner({
secret: process.env.NEXT_PUBLIC_SIGNING_SECRET!,
algorithm: "SHA-256",
});
const { headers } = await signer.sign({
method: "POST",
path: "/upload-url",
body: JSON.stringify(payload),
nonce: generateNonce(),
});Attach returned headers to the request:
x-signaturex-timestamp- optional
x-nonce
Nonce Replay Protection
For stronger replay protection:
- enable
requireNonce: true - provide
nonceStore - generate a unique nonce per request
If requireNonce is enabled and no nonceStore is passed, the middleware uses an in-memory nonce store.
Failure Behavior
Verification failures return typed security errors such as:
SIGNATURE_MISSINGSIGNATURE_INVALIDTIMESTAMP_MISSINGTIMESTAMP_EXPIREDNONCE_MISSINGNONCE_REUSED
Use onVerificationFailure to return a custom Response.
Recommended Pattern
- Sign all client storage requests.
- Verify signatures before auth/rate-limit dependent business logic.
- Use nonce + timestamp tolerance in production.