API security headers
Driftstack's HTTP API sets a fixed, reviewable set of security headers on every response. This page documents what they are and why, so security reviewers don't have to derive it from a production capture.
Always-on transport headers
| Header | Value | Why |
|---|---|---|
Strict-Transport-Security | max-age=63072000; includeSubDomains; preload | 2-year HSTS, eligible for the browser preload list. Closes first-visit downgrade attacks before TLS upgrade kicks in. |
X-Content-Type-Options | nosniff | Browsers must not infer MIME types from content. |
X-Frame-Options | SAMEORIGIN | Driftstack ships no embeddable UI; framing is disallowed by default. |
Referrer-Policy | no-referrer | No referrer leakage to third parties. |
X-DNS-Prefetch-Control | off | Disables speculative DNS for embedded URLs. |
Cache-Control posture
| Path | Cache-Control |
|---|---|
/v1/account/* | no-store, private |
/v1/admin/* | no-store, private |
/v1/billing/* | no-store, private |
/v1/status (public) | public, max-age=30 |
/v1/status/stream (SSE) | no-cache, no-transform |
Endpoints under /v1/account/*,
/v1/admin/*, and /v1/billing/* return
caller-private dynamic state. They are auth-gated at the
request layer; the no-store, private header is
defense-in-depth so shared / proxy caches can't hold onto
private payloads and browser back-forward cache can't serve
stale state after logout.
CORS
The API uses an explicit allow-list of origins; SDK consumers
can call from any origin because the SDK ships
Authorization: Bearer … and never relies on
browser-cookie auth. Pre-flight responses cache for 10 minutes.
credentials: true is required only by the
Driftstack customer dashboard's cookie-based session
(Article-13 auth).
Access-Control-Allow-Origin: <reflected allow-list match>
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Headers: authorization, content-type, x-request-id, stripe-signature, x-nowpayments-sig
Access-Control-Expose-Headers: x-request-id, x-ratelimit-bucket, x-ratelimit-limit, x-ratelimit-remaining, x-ratelimit-reset, ratelimit-limit, ratelimit-remaining, ratelimit-reset, retry-after
Access-Control-Max-Age: 600
Access-Control-Allow-Credentials: true Cross-Origin resource policy
Cross-Origin-Resource-Policy: cross-origin is set
explicitly. The default helmet value
(same-origin) would block legitimate SDK calls
from third-party origins because the CORS layer is our
boundary, not CORP.
What we don't set
- Content-Security-Policy. Driftstack serves no HTML — every endpoint returns JSON, plain text, CSV, or PDF. CSP would be a no-op.
- Cross-Origin-Embedder-Policy. Same logic — no embeddable surfaces.
- Cookie security flags. The public REST API
is bearer-auth only. The dashboard's Article-13 cookie sets
Secure; HttpOnly; SameSite=Lax; that's documented separately.
Reporting a finding
Send disclosures to [email protected]. PGP key on security.txt. Our policy + bounty range is on the vulnerability-disclosure policy.