> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentfront.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Security Headers & CSP

> Configure Content Security Policy, HSTS, and other security headers via frontmcp.config or environment variables

FrontMCP applies security headers to every HTTP response, including Content Security Policy (CSP), Strict-Transport-Security (HSTS), X-Frame-Options, and X-Content-Type-Options. `X-Content-Type-Options: nosniff` and `X-Frame-Options: DENY` are on by default, and `X-Powered-By` is never sent. Configure the rest with `frontmcp.config` server settings, with `@FrontMcp({ http: { securityHeaders } })`, or with `FRONTMCP_*` environment variables. The Express host and the fetch handler used on Cloudflare Workers, Vercel Edge and Deno share one resolver, so both send the same headers.

## Quick Start

Add security headers to `frontmcp.config.ts`:

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
import { defineConfig } from 'frontmcp';

export default defineConfig({
  name: 'my-server',
  deployments: [{
    target: 'node',
    server: {
      csp: {
        enabled: true,
        directives: {
          'default-src': "'self'",
          'script-src': "'self' https://cdn.example.com",
          'upgrade-insecure-requests': '',
        },
        reportOnly: false,
      },
      headers: {
        hsts: 'max-age=31536000; includeSubDomains',
        contentTypeOptions: 'nosniff',
        frameOptions: 'DENY',
      },
    },
  }],
});
```

`frontmcp dev` passes this config to the server as environment variables. The `cloudflare`, `vercel`, `lambda` and `distributed` builds write them into the generated `serverless-setup.js`, and only where the platform has not already set that variable, so a real environment variable always wins. The `node` target has no setup file: set the `FRONTMCP_*` variables where the server runs, or configure `http.securityHeaders` on `@FrontMcp` (see below).

## CSP Configuration

| Field | Type | Default | Description |
| - | - | - | - |
| `enabled` | boolean | `false` | Enable CSP headers |
| `directives` | `Record<string, string \| string[]>` | --- | Map of directive name to value(s) |
| `reportUri` | string | --- | URI for CSP violation reports |
| `reportOnly` | boolean | `false` | Use `Content-Security-Policy-Report-Only` instead of enforcement |

<Tip>
  Value-less CSP directives like `upgrade-insecure-requests` and `block-all-mixed-content` are supported — set the value to an empty string (`''`).
</Tip>

### Example Directives

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
directives: {
  'default-src': "'self'",
  'script-src': "'self' https://cdn.example.com",
  'style-src': "'self' 'unsafe-inline'",
  'img-src': '*',
  'upgrade-insecure-requests': '',
}
```

## Security Headers

| Header | Config Field | Default | Description |
| - | - | - | - |
| `Strict-Transport-Security` | `headers.hsts` | --- | HSTS policy for HTTPS enforcement |
| `X-Content-Type-Options` | `headers.contentTypeOptions` | `nosniff` | Prevent MIME type sniffing |
| `X-Frame-Options` | `headers.frameOptions` | `DENY` | Clickjacking protection |
| Custom headers | `headers.custom` | --- | Record of additional header name-value pairs |

<Note>
  `X-Content-Type-Options: nosniff` and `X-Frame-Options: DENY` are applied by default even without explicit configuration. Set `contentTypeOptions` or `frameOptions` to `false` to omit the header (the environment variable equivalent is `off`).
</Note>

## Decorator Option

The same settings can live on `@FrontMcp`. This is the only route that works on every target without a build step:

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
@FrontMcp({
  info: { name: 'my-server', version: '1.0.0' },
  http: {
    securityHeaders: {
      hsts: 'max-age=31536000; includeSubDomains',
      frameOptions: 'SAMEORIGIN',
      csp: { enabled: true, directives: { 'default-src': ["'self'"] } },
      custom: { 'Referrer-Policy': 'no-referrer' },
    },
  },
})
class Server {}
```

Precedence, highest first: `http.securityHeaders`, then the `FRONTMCP_*` variables, then the defaults. `csp.enabled: false` in the decorator overrides `FRONTMCP_CSP_ENABLED`.

## Environment Variables

The settings map to these variables (see the note above for which commands set them for you):

| Variable | Maps To |
| - | - |
| `FRONTMCP_CSP_ENABLED` | `server.csp.enabled` |
| `FRONTMCP_CSP_DIRECTIVES` | `server.csp.directives` |
| `FRONTMCP_CSP_REPORT_URI` | `server.csp.reportUri` |
| `FRONTMCP_CSP_REPORT_ONLY` | `server.csp.reportOnly` |
| `FRONTMCP_HSTS` | `server.headers.hsts` |
| `FRONTMCP_CONTENT_TYPE_OPTIONS` | `server.headers.contentTypeOptions` |
| `FRONTMCP_FRAME_OPTIONS` | `server.headers.frameOptions` |
| `FRONTMCP_HEADERS_CUSTOM` | `server.headers.custom` (a JSON object) |

`FRONTMCP_HSTS`, `FRONTMCP_CONTENT_TYPE_OPTIONS` and `FRONTMCP_FRAME_OPTIONS` accept `off`, `false` or `none` to omit the header. A malformed `FRONTMCP_HEADERS_CUSTOM` is ignored.

You can set or override these at runtime without rebuilding:

```bash theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
FRONTMCP_CSP_ENABLED=1 \
FRONTMCP_CSP_DIRECTIVES="default-src 'none'" \
FRONTMCP_HSTS="max-age=0" \
node dist/main.js
```

## Programmatic Access

For built-in HTTP transport targets, FrontMCP applies the configured security headers during HTTP response handling. For custom transport adapters, header application is your adapter's responsibility — wire equivalent logic into the response pipeline yourself. The internal helper utilities are not part of the public `@frontmcp/sdk` API; if you need them re-exported, open a feature request rather than importing from repository-internal source paths.

## Report-Only Mode

Use `reportOnly: true` to test CSP rules without blocking content:

```typescript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
server: {
  csp: {
    enabled: true,
    directives: {
      'default-src': "'self'",
    },
    reportUri: 'https://report.example.com/csp',
    reportOnly: true,  // violations are reported, not blocked
  },
}
```

This sets the `Content-Security-Policy-Report-Only` header instead of `Content-Security-Policy`, allowing you to monitor violations before enforcing the policy.

## Related

<CardGroup cols={2}>
  <Card title="Configuration File" icon="file-code" href="/frontmcp/deployment/frontmcp-config">
    Full configuration reference
  </Card>

  <Card title="Production Build" icon="rocket" href="/frontmcp/deployment/production-build">
    Build and deploy for production
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.