HTTP Security Headers
Configure LibreChat's baseline HTTP security headers and nonce-based Content Security Policy
LibreChat sends a baseline set of HTTP security headers on every response, including health endpoints. A nonce-based Content Security Policy (CSP) is available separately and is disabled by default so existing integrations can be audited before enforcement.
Baseline Headers
Baseline headers are enabled unless SECURITY_HEADERS=false. That variable is the global kill switch: it disables both the baseline headers and CSP.
| Variable | Default | Behavior |
|---|---|---|
SECURITY_HEADERS | true | Enables all baseline headers. false also disables CSP. |
HSTS_ENABLED | true | Sends Strict-Transport-Security. Browsers honor it only over HTTPS. |
HSTS_MAX_AGE | 31536000 | HSTS lifetime in seconds. Must be a non-negative integer. |
HSTS_INCLUDE_SUBDOMAINS | false | Applies HSTS to every subdomain. Enable only when all subdomains use HTTPS. |
HSTS_PRELOAD | false | Adds the HSTS preload token. |
X_FRAME_OPTIONS | SAMEORIGIN | Accepts SAMEORIGIN, DENY, or off. |
REFERRER_POLICY | no-referrer | Sets Referrer-Policy; use off to omit it. |
CROSS_ORIGIN_OPENER_POLICY | same-origin | Sets Cross-Origin-Opener-Policy; use off to omit it. |
CROSS_ORIGIN_RESOURCE_POLICY | same-origin | Sets Cross-Origin-Resource-Policy; use off to omit it. |
Helmet also sends X-Content-Type-Options: nosniff. Invalid values are logged and fall back to the documented defaults.
Accepted opener policies are same-origin, same-origin-allow-popups, noopener-allow-popups, and unsafe-none. Accepted resource policies are same-origin, same-site, and cross-origin. Accepted referrer policies are no-referrer, no-referrer-when-downgrade, same-origin, origin, strict-origin, origin-when-cross-origin, strict-origin-when-cross-origin, and unsafe-url.
SECURITY_HEADERS=true
HSTS_ENABLED=true
HSTS_MAX_AGE=31536000
HSTS_INCLUDE_SUBDOMAINS=false
HSTS_PRELOAD=false
X_FRAME_OPTIONS=SAMEORIGIN
REFERRER_POLICY=no-referrer
CROSS_ORIGIN_OPENER_POLICY=same-origin
CROSS_ORIGIN_RESOURCE_POLICY=same-originIf an upstream proxy also writes these headers, keep one authoritative policy and verify the final response seen by the browser.
Content Security Policy
CSP is opt-in. LibreChat creates a fresh nonce for every SPA response and applies it to executable scripts and module-preload links in the shell.
Start in report-only mode
Enable CSP with CSP_REPORT_ONLY=true, collect violations from your real deployment, add only the required sources, and enforce only after the app, authentication, storage, telemetry, and embedded-content flows are clean.
CSP_ENABLED=true
CSP_REPORT_ONLY=true
CSP_REPORT_URI=https://reports.example.com/csp
# Examples for deployment-specific services
CSP_CONNECT_SRC_EXTRA="https://telemetry.example.com wss://stream.example.com"
CSP_FRAME_SRC_EXTRA=https://tenant.sharepoint.com
CSP_IMG_SRC_EXTRA=https://cdn.example.comCSP_REPORT_ONLY defaults to true. Only a recognized false value switches to enforcement; an unrecognized value is logged and remains report-only. While CSP is enabled, LibreChat forces the SPA shell to Cache-Control: no-store and ignores INDEX_CACHE_CONTROL, INDEX_PRAGMA, and INDEX_EXPIRES for that response so a nonce cannot be reused from cache.
CSP Variables
| Variable | Default | Behavior |
|---|---|---|
CSP_ENABLED | false | Enables nonce-based CSP for the SPA shell. |
CSP_REPORT_ONLY | true | Sends Content-Security-Policy-Report-Only; set false to enforce. |
CSP_REPORT_URI | empty | Adds the legacy report-uri directive. |
CSP_ALLOW_WASM | true | Allows WebAssembly compilation used by HEIC conversion. |
CSP_ALLOW_DATA_WORKERS | true | Allows data: workers used by Monaco's loader. |
CSP_FRAME_ANCESTORS | 'self' | Replaces the complete frame-ancestors source list. |
CSP_ADDITIONAL_DIRECTIVES | empty | Adds semicolon-separated raw directives. |
These variables append sources to the matching built-in directive:
CSP_DEFAULT_SRC_EXTRACSP_SCRIPT_SRC_EXTRACSP_STYLE_SRC_EXTRACSP_IMG_SRC_EXTRACSP_FONT_SRC_EXTRACSP_CONNECT_SRC_EXTRACSP_MEDIA_SRC_EXTRACSP_FRAME_SRC_EXTRACSP_WORKER_SRC_EXTRACSP_FORM_ACTION_EXTRA
Source lists can be comma- or space-separated. They append rather than replace LibreChat's defaults. CSP_FRAME_ANCESTORS is the exception because it intentionally replaces the default 'self' value.
The default script policy uses 'strict-dynamic'. Setting CSP_SCRIPT_SRC_EXTRA removes 'strict-dynamic' so the listed script hosts can take effect. List only origins you trust to execute code in LibreChat.
If another origin must frame LibreChat, enforce frame-ancestors before removing X-Frame-Options:
CSP_ENABLED=true
CSP_REPORT_ONLY=false
X_FRAME_OPTIONS=off
CSP_FRAME_ANCESTORS="'self' https://portal.example.com"Do not set X_FRAME_OPTIONS=off while CSP is disabled or report-only. A report-only policy records violations but does not restrict framing, so removing X-Frame-Options first would allow any origin to frame the deployment. Browsers without frame-ancestors support will not enforce a framing restriction in this cross-origin setup.
See the environment variable reference for where these settings live in .env.
How is this guide?