headers

js/security/headers.ts

fino:security/headers - backend security header helpers.

Builds conservative HTTP response headers for common browser-facing backend policies. The helpers only format configured header values; they do not inspect requests, enforce browser policy locally, or validate full CSP grammars. Applications should still test the resulting policy in target browsers.

Learn more:

Types

type HeaderMap = Record<string, string>

Case-insensitive HTTP header map represented with lower-case names.

Header builders in this module normalize names to lower-case and store one string value per header. Duplicate header semantics, such as appending multiple Set-Cookie values, are outside this simple map shape.

import type { HeaderMap } from 'fino:security/headers';

const headers: HeaderMap = { 'x-content-type-options': 'nosniff' };

Interfaces

interface SecurityHeadersOptions {

Options controlling the default backend security headers.

Omitted options use conservative defaults. Passing false disables headers that support opt-out. extra is merged last, so it can override defaults or add application-specific headers.

import type { SecurityHeadersOptions } from 'fino:security/headers';

const options: SecurityHeadersOptions = {
  frameOptions: 'SAMEORIGIN',
  contentSecurityPolicy: "default-src 'self'",
};

Properties

contentSecurityPolicy?: string | false

Optional Content Security Policy value.

The default is omitted because CSP must be tailored to the application. Pass a string to emit content-security-policy, or false to make the opt-out explicit.

import { createSecurityHeaders } from 'fino:security/headers';

createSecurityHeaders({ contentSecurityPolicy: "default-src 'self'" });
frameOptions?: 'DENY' | 'SAMEORIGIN' | false

Value for x-frame-options, or false to omit it.

Defaults to DENY. Use SAMEORIGIN when same-site framing is required.

import type { SecurityHeadersOptions } from 'fino:security/headers';

const options: SecurityHeadersOptions = { frameOptions: 'SAMEORIGIN' };
referrerPolicy?: string | false

Value for referrer-policy, or false to omit it.

Defaults to no-referrer. Choose a looser policy only when downstream analytics or cross-origin flows need referrer data.

import type { SecurityHeadersOptions } from 'fino:security/headers';

const options: SecurityHeadersOptions = { referrerPolicy: 'strict-origin' };
strictTransportSecurity?: string | false

Value for strict-transport-security, or false to omit it.

Defaults to max-age=31536000; includeSubDomains. Only emit HSTS on HTTPS origins that are ready to enforce HTTPS for the configured scope.

import type { SecurityHeadersOptions } from 'fino:security/headers';

const options: SecurityHeadersOptions = { strictTransportSecurity: false };
permissionsPolicy?: string | false

Value for permissions-policy, or false to omit it.

The default is omitted because allowed browser features depend on the app.

import type { SecurityHeadersOptions } from 'fino:security/headers';

const options: SecurityHeadersOptions = { permissionsPolicy: 'geolocation=()' };
crossOriginOpenerPolicy?: string | false

Value for cross-origin-opener-policy, or false to omit it.

Defaults to same-origin, which helps isolate browsing contexts. Disable or relax it only for integrations that require opener access.

import type { SecurityHeadersOptions } from 'fino:security/headers';

const options: SecurityHeadersOptions = { crossOriginOpenerPolicy: 'same-origin-allow-popups' };
extra?: HeaderMap

Additional headers merged after the defaults.

Names are normalized to lower-case, and later values take precedence.

import type { SecurityHeadersOptions } from 'fino:security/headers';

const options: SecurityHeadersOptions = { extra: { 'x-robots-tag': 'noindex' } };

Functions

function createSecurityHeaders(options: SecurityHeadersOptions = {}): HeaderMap

Build conservative security headers for backend HTTP responses.

Defaults include x-content-type-options: nosniff, x-frame-options: DENY, referrer-policy: no-referrer, HSTS, and COOP. CSP and permissions policy are emitted only when supplied. Header names are lower-case and extra values override generated defaults.

import { createSecurityHeaders } from 'fino:security/headers';

const headers = createSecurityHeaders({
  contentSecurityPolicy: "default-src 'self'",
});

function mergeHeaders(...sets: Array<HeaderMap | undefined>): HeaderMap

Merge header maps using lower-case names and later values taking precedence.

undefined sets are skipped. Values are coerced with String(), so pass preformatted header values rather than arrays. This helper is best for single-value headers, not multi-value Set-Cookie output.

import { mergeHeaders } from 'fino:security/headers';

const headers = mergeHeaders(
  { 'X-Content-Type-Options': 'nosniff' },
  { 'x-content-type-options': 'nosniff' },
);