/** * Copyright (c) 2026 AzerothJS. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ /** * Baseline response security headers. * * The zero-dependency answer to helmet: a set of well-understood response headers, safe * defaults on, each one overridable or removable. A DEFAULT applies only where the response * does not already carry that header - a handler's own choice for one route wins - while a * value passed here explicitly always wins. Nothing here is application policy (a CSP or a * Permissions-Policy is yours to author) - these are the headers that are correct for almost * every server and forgotten by almost every one that does not use a library. * * Defaults set: X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Cross-Origin-Opener- * Policy, Cross-Origin-Resource-Policy, X-DNS-Prefetch-Control. HSTS, Permissions-Policy, and * CSP are opt-in - each can break a working app if applied blindly, so you turn them on * deliberately. HSTS additionally refuses to emit over a plaintext hop: a Strict-Transport- * Security header on http would pin clients to a scheme this connection cannot prove, and a * client-forgeable `x-forwarded-proto` claim counts only under `trustProxy` - the same * boundary `clientIp` is built on. */ import { type EdgeMiddleware } from './edge.ts'; /** * HSTS for {@link securityHeaders}. Emitted only over a connection proven secure - sending it * on plain HTTP is meaningless, and a wrong `maxAge` with `preload` is close to irreversible, * which is why nothing here defaults to preload. */ export interface HstsOptions { /** max-age in seconds (default 15552000 = 180 days). */ maxAgeSeconds?: number; /** Add `includeSubDomains` (default true). */ includeSubDomains?: boolean; /** Add `preload` - only set this if you have submitted the domain to the preload list. */ preload?: boolean; } /** Each header defaults to a safe value; set `false` to omit it, or a string to override it. */ export interface SecurityHeadersOptions { /** X-Content-Type-Options (default `nosniff`). */ contentTypeOptions?: string | false; /** X-Frame-Options (default `SAMEORIGIN`). CSP `frame-ancestors` is the modern successor. */ frameOptions?: string | false; /** Referrer-Policy (default `no-referrer`). */ referrerPolicy?: string | false; /** Cross-Origin-Opener-Policy (default `same-origin`). */ crossOriginOpenerPolicy?: string | false; /** Cross-Origin-Resource-Policy (default `same-origin`). */ crossOriginResourcePolicy?: string | false; /** X-DNS-Prefetch-Control (default `off`). */ dnsPrefetchControl?: string | false; /** Strict-Transport-Security - OFF by default; enable only when serving over HTTPS. */ hsts?: HstsOptions | false; /** Permissions-Policy value - OFF by default (app-specific; a wrong value disables features). */ permissionsPolicy?: string | false; /** Content-Security-Policy value - OFF by default (author it for your app). */ contentSecurityPolicy?: string | false; /** * Believe `x-forwarded-proto` when deciding the hop is secure enough for HSTS (default * false). The header is client-forgeable, so it counts only behind a proxy you declared - * the same trust boundary as `clientIp`. */ trustProxy?: boolean; } /** * Adds baseline security headers to every response. A default applies only where the response * does not already carry that header, so a handler's stricter per-route choice survives; a * value passed here explicitly always wins. Pass `false` to drop a header, or enable the * opt-in ones (HSTS, Permissions-Policy, CSP). HSTS is emitted only over a proven-secure * connection: TLS on the URL, or a forwarded-proto claim under `trustProxy`. */ export declare function securityHeaders(options?: SecurityHeadersOptions): EdgeMiddleware;