---
title: Security Headers
description: Security headers used to protect your application.
---

import { Authors } from '/snippets/authors.mdx';

<Authors data={[{
  user: {
    name: 'Hayden Bleasel',
    id: 'haydenbleasel',
  },
  company: {
    name: 'next-forge',
    id: 'next-forge',
  },
}, {
  user: {
    name: 'David Mytton',
    id: 'davidmytton',
  },
  company: {
    name: 'Arcjet',
    id: 'arcjet',
  },
}]} />

next-forge uses [Nosecone](https://docs.arcjet.com/nosecone/quick-start) to set HTTP response headers related to security.

## Configuration

Here are the headers we have enabled:

- `Cross-Origin-Embedder-Policy` (COEP)
- `Cross-Origin-Opener-Policy`
- `Cross-Origin-Resource-Policy`
- `Origin-Agent-Cluster`
- `Referrer-Policy`
- `Strict-Transport-Security` (HSTS)
- `X-Content-Type-Options`
- `X-DNS-Prefetch-Control`
- `X-Download-Options`
- `X-Frame-Options`
- `X-Permitted-Cross-Domain-Policies`
- `X-XSS-Protection`

See the [Nosecone reference](https://docs.arcjet.com/nosecone/reference) for details on each header and configuration options.

## Usage

Recommended headers are set by default and configured in `@repo/security/middleware`. Changing the configuration here will affect all apps.

They are then attached to the response within the middleware in `apps/app/middleware` and `apps/web/middleware.ts`. Adjusting the configuration in these files will only affect the specific app.

## Content Security Policy (CSP)

The CSP header is not set by default because it requires specific configuration based on the next-forge features you have enabled.

In the meantime, you can set the CSP header using the Nosecone configuration. For example, the following CSP configuration will work with the default next-forge features:

```ts
import type { NoseconeOptions } from '@nosecone/next';
import { defaults as noseconeDefaults } from '@nosecone/next';

const noseconeOptions: NoseconeOptions = {
  ...noseconeDefaults,
  contentSecurityPolicy: {
    ...noseconeDefaults.contentSecurityPolicy,
    directives: {
      ...noseconeDefaults.contentSecurityPolicy.directives,
      scriptSrc: [
        // We have to use unsafe-inline because next-themes and Vercel Analytics
        // do not support nonce
        // https://github.com/pacocoursey/next-themes/issues/106
        // https://github.com/vercel/analytics/issues/122
        //...noseconeDefaults.contentSecurityPolicy.directives.scriptSrc,
        "'self'",
        "'unsafe-inline'",
        "https://www.googletagmanager.com",
        "https://*.clerk.accounts.dev",
        "https://va.vercel-scripts.com",
      ],
      connectSrc: [
        ...noseconeDefaults.contentSecurityPolicy.directives.connectSrc,
        "https://*.clerk.accounts.dev",
        "https://*.google-analytics.com",
        "https://clerk-telemetry.com",
      ],
      workerSrc: [
        ...noseconeDefaults.contentSecurityPolicy.directives.workerSrc,
        "blob:",
        "https://*.clerk.accounts.dev"
      ],
      imgSrc: [
        ...noseconeDefaults.contentSecurityPolicy.directives.imgSrc,
        "https://img.clerk.com"
      ],
      objectSrc: [
        ...noseconeDefaults.contentSecurityPolicy.directives.objectSrc,
      ],
      // We only set this in production because the server may be started
      // without HTTPS
      upgradeInsecureRequests: process.env.NODE_ENV === "production",
    },
  },
}
```

