StreamPay computes a stable request fingerprint for fraud signal correlation
on every /api/* request. The fingerprint is a SHA-256 hash of normalized,
non-volatile request signals and is intentionally separate from idempotency
fingerprints (which include request bodies).
| Signal | Source | Normalization |
|---|---|---|
| HTTP method | request.method |
Uppercase |
| Pathname | Request URL | Trailing slashes removed |
| Client IP | x-forwarded-for (first hop), x-real-ip, cf-connecting-ip, true-client-ip |
Lowercase; falls back to unknown |
| User-Agent | user-agent header |
Trimmed, lowercased |
| Accept-Language | accept-language header |
Primary tag only, lowercased |
| Accept-Encoding | accept-encoding header |
Sorted, lowercased |
The fingerprint must remain stable across retries and must not leak secrets:
- Request body and query parameters
- Cookies, authorization headers, and idempotency keys
- Request IDs, correlation IDs, and timestamps
- Edge middleware (
middleware.ts) computes the fingerprint vialib/fingerprint.ts. - The hash is attached to the downstream request as
x-request-fingerprint. - Node server code registers an audit hook (
lib/fingerprint-audit.ts) that appendsrequest.fingerprint.capturedentries to the audit log with the incomingx-request-id/x-correlation-id. - Privileged stream audit events automatically include
requestFingerprintmetadata when the header is present.
There is no public response field for the fingerprint. It is an internal header
used for fraud correlation and audit enrichment only. External clients must not
send or rely on x-request-fingerprint.
Run the focused domain tests:
npm test -- lib/fingerprint.test.ts lib/fingerprint-audit.test.ts middleware.test.tsCoverage targets edge cases such as forwarded IP chains, header normalization, invalid fingerprint headers, and middleware propagation on both success and 413 error paths.