withSecurityHeaders function is a utility for adding a small set of security-related HTTP headers to a Response. It's fully opt-in, nothing else in @arkyn/server calls it automatically, you wrap the responses you want it applied to.ts
import { withSecurityHeaders } from "@arkyn/server/withSecurityHeaders";// orimport { withSecurityHeaders } from "@arkyn/server";
response (required)Response object to add headers to. Its headers are mutated in place, the same instance is returned. The headers must be mutable, see Notes below.Responseoverrides (optional){ ...defaults, ...overrides }). A string value replaces or adds that header, any header name is allowed; null removes it (useful to opt a default header back out).Record<string, string | null>X-Content-Type-Options: nosniffX-Frame-Options: DENYReferrer-Policy: strict-origin-when-cross-originContent-Security-Policy and Strict-Transport-Security are deliberately not set by default, both are too app-specific to guess safely: a wrong CSP can break an app's own scripts, and HSTS assumes HTTPS is already correctly configured elsewhere. Add either through overrides if your app needs them.Response instance it was given, with headers added.Responsetypescript
import { Success } from "@arkyn/server/success";import { withSecurityHeaders } from "@arkyn/server/withSecurityHeaders";// Apply the defaultsreturn withSecurityHeaders(new Success("OK", { data }).toResponse());// Add a Content-Security-Policy, and opt out of X-Frame-Optionsreturn withSecurityHeaders(new Success("OK", { data }).toResponse(), {"Content-Security-Policy": "default-src 'self'","X-Frame-Options": null,});
new Response(), Response.json(), and Arkyn's toResponse() are fine. A Response returned by fetch() or created with Response.redirect() has immutable headers, and passing one throws a TypeError. To add headers to a proxied fetch() response, copy it first:typescript
const upstream = await fetch("https://api.example.com/data");return withSecurityHeaders(new Response(upstream.body, upstream));
Response instance passed in, it does not clone the response. Existing headers, body, status, and statusText are all preserved.