# clerkMiddleware()

The `clerkMiddleware()` function checks the request's cookies and headers for a session JWT and if found, attaches the [`Auth`](https://clerk.com/docs/reference/backend/types/auth-object.md) object to the `request` object under the `auth` key. **It must be set before any other middleware.**

> Use `clerkMiddleware()` with [`getAuth()`](https://clerk.com/docs/expressjs/reference/get-auth.md) to protect routes while keeping control over unauthenticated responses. See the [example](#example-use-clerkmiddleware-and-getauth-together).

```js
import { clerkMiddleware } from '@clerk/express'

const app = express()

// Pass no parameters
app.use(clerkMiddleware())

// Pass options
app.use(clerkMiddleware(options))
```

## Example: Use `clerkMiddleware()` and `getAuth()` together

The following example demonstrates how to use `clerkMiddleware()` and [`getAuth()`](https://clerk.com/docs/expressjs/reference/get-auth.md) together. `clerkMiddleware()` provides authentication state to your routes, and `getAuth()` protects a route based on authentication and authorization status.

```js
import { clerkMiddleware, getAuth } from '@clerk/express'
import express from 'express'

const app = express()
const PORT = 3000

// Apply `clerkMiddleware()` to all routes
app.use(clerkMiddleware())

app.get('/path', (req, res) => {
  // Use `getAuth()` to protect a route based on authorization status
  const auth = getAuth(req)

  // Handle if the user is not authenticated
  if (!auth.isAuthenticated) {
    res.status(401).send('Unauthorized')
    return
  }

  // Handle if the user is authenticated but not authorized
  if (!auth.has({ permission: 'org:admin:example' })) {
    res.status(403).send('Forbidden')
    return
  }

  res.json(auth)
})

// This route is not protected but it will have authentication state
// attached to the request object because `clerkMiddleware()` was applied to all routes
app.get('/path2', (req, res) => {
  res.json(getAuth(req))
})

// Start the server and listen on the specified port
app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`)
})
```

### `clerkMiddleware()` options

The `clerkMiddleware()` function accepts an optional object. The following options are available:

| Name                     | Type                                 | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------------ | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| audience?                | string | string[]                  | A string or list of audiences. If passed, it is checked against the aud claim in the token.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| authorizedParties?       | string[]                            | An allowlist of origins to verify against, to protect your application from the subdomain cookie leaking attack. For example: ['http://localhost:3000', 'https://example.com']                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| clockSkewInMs?           | number                               | Specifies the allowed time difference (in milliseconds) between the Clerk server (which generates the token) and the clock of the user's application server when validating a token. Defaults to 5000 ms (5 seconds).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| domain?                  | string                               | The domain used for satellites to inform Clerk where this application is deployed.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| frontendApiProxy?        | FrontendApiProxyOptions              | Configure Frontend API proxy handling. When enabled, requests to the proxy path are forwarded to Clerk's Frontend API, and the proxyUrl is automatically derived for authentication handshake.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| isSatellite?             | boolean                              | When using Clerk's satellite feature, this should be set to true for secondary domains.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| jwtKey                   | string                               | Used to verify the session token in a networkless manner. Supply the JWKS Public Key from the API keys page in the Clerk Dashboard. It's recommended to use the environment variable instead. For more information, refer to Manual JWT verification.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| organizationSyncOptions? | OrganizationSyncOptions | undefined | Used to activate a specific Organization or Personal AccountPersonal Accounts are individual workspaces that allow users to operate independently without belonging to an Organization. Learn more about Personal Accounts. based on URL path parameters. If there's a mismatch between the Active OrganizationA user can be a member of multiple Organizations, but only one can be active at a time. The Active Organization determines which Organization-specific data the user can access and which Role and related Permissions they have within the Organization. in the session (e.g., as reported by auth()) and the Organization indicated by the URL, the middleware will attempt to activate the Organization specified in the URL. |
| proxyUrl?                | string                               | Specify the URL of the proxy, if using a proxy.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| publishableKey           | string                               | The Clerk Publishable KeyYour Clerk Publishable Key tells your app what your FAPI URL is, enabling your app to locate and communicate with your dedicated FAPI instance. You can find it on the API keys page in the Clerk Dashboard. for your instance.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| satelliteAutoSync?       | boolean                              | Controls whether a satellite app automatically syncs authentication state with the primary domain on first page load. When false (default), the satellite app skips the automatic redirect if no session cookies exist, and only triggers the handshake after the user initiates a sign-in or sign-up action. When true, the satellite app redirects to the primary domain on every first visit to sync state. Defaults to false. See satellite domains for more details.                                                                                                                                                                                                                                                                       |
| secretKey?               | string                               | The Clerk Secret KeyYour Clerk Secret Key is used to authenticate requests from your backend to Clerk's API. You can find it on the API keys page in the Clerk Dashboard. Do not expose this on the frontend with a public environment variable. for your instance. The CLERK\_ENCRYPTION\_KEY environment variable must be set when providing secretKey as an option, refer to Dynamic keys.                                                                                                                                                                                                                                                                                                                                                   |
| signInUrl                | string                               | The full URL or path to your sign-in page. Needs to point to your primary application on the client-side. Required for a satellite application in a development instance. It's recommended to use the environment variable instead.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| signUpUrl                | string                               | The full URL or path to your sign-up page. Needs to point to your primary application on the client-side. Required for a satellite application in a development instance. It's recommended to use the environment variable instead.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |

| Name        | Type        | Description                                                                                                                 |
| ----------- | ----------- | --------------------------------------------------------------------------------------------------------------------------- |
| clerkClient | ClerkClient | An instance of the ClerkClient class. This is used to interact with the Clerk API.                                          |
| debug       | boolean     | A flag to enable debug mode. When set to true, the middleware will log debug information to the console. Defaults to false. |

### Frontend API proxy

The `frontendApiProxy` option enables built-in proxying of Clerk Frontend API requests through your application. Use this when requests to Clerk's API cannot be made directly from the browser and must be routed through your server.

When enabled, requests matching the proxy path (by default, `/__clerk`) are intercepted and forwarded to [Clerk's Frontend API](https://clerk.com/docs/reference/frontend-api) before authentication runs. The `proxyUrl` used for authentication handshake is automatically derived.

> For production instances, you must also [enable proxying](https://clerk.com/docs/guides/dashboard/dns-domains/proxy-fapi.md#enable-proxying) in the Clerk Dashboard. For both development and production instances, configure the client-side proxy URL so ClerkJS routes browser requests through your proxy.

```js
import { clerkMiddleware } from '@clerk/express'
import express from 'express'

const app = express()

// Enable proxy with default path ('/__clerk')
app.use(
  clerkMiddleware({
    frontendApiProxy: {
      enabled: true,
    },
  }),
)

// Or with a custom proxy path
app.use(
  clerkMiddleware({
    frontendApiProxy: {
      enabled: true,
      path: '/custom-clerk-proxy',
    },
  }),
)
```

#### `FrontendApiProxyOptions`

| Name    | Type                               | Description                                                                                                                                                                              |
| ------- | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| enabled | boolean | ((url: URL) => boolean) | Enable Frontend API proxy handling. When true, requests to the proxy path are forwarded to Clerk's Frontend API, and the proxyUrl is automatically derived for authentication handshake. |
| path?   | string                             | The path prefix for proxy requests. Defaults to '/\_\_clerk'. Must be unique and not conflict with other routes in your application.                                                     |

#### `OrganizationSyncOptions`

The `organizationSyncOptions` property on the [`clerkMiddleware()`](#clerkmiddleware-options) options
object has the type `OrganizationSyncOptions`, which has the following properties:

| Name                                  | Type                                | Description |
| ------------------------------------- | ----------------------------------- | ----------- |
| ["/orgs/:slug", "/orgs/:slug/(.\*)"] | ["/orgs/:id", "/orgs/:id/(.\*)"]   |             |
| ["/me", "/me/(.\*)"]                 | ["/user/:any", "/user/:any/(.\*)"] |             |

> Organization activation from `organizationSyncOptions` relies on Clerk's [handshake](https://clerk.com/docs/guides/how-clerk-works/overview.md#the-handshake), which redirects the browser to Clerk's Frontend API. The handshake only runs for requests that look like document navigations — a `GET` request whose `Sec-Fetch-Dest` is `document` or `iframe`, or (for clients that don't send `Sec-Fetch-Dest`) a `GET` request with an `Accept: text/html` header. As a result, `organizationSyncOptions` won't set the active Organization for browser `fetch()`/`XHR` calls or WebSocket upgrades, which never carry those headers. When you need Organization context in those code paths, set the active Organization explicitly with [setActive()](https://clerk.com/docs/reference/objects/clerk.md#setactive) before opening the WebSocket or making the request.

### Pattern

A `Pattern` is a `string` that represents the structure of a URL path. In addition to any valid URL, it may include:

- Named path parameters prefixed with a colon (e.g., `:id`, `:slug`, `:any`).
- Wildcard token, `(.*)`, which matches the remainder of the path.

#### Examples

- `/orgs/:slug`

| URL                       | Matches | `:slug` value |
| ------------------------- | ------- | ------------- |
| `/orgs/acmecorp`          | ✅       | `acmecorp`    |
| `/orgs`                   | ❌       | n/a           |
| `/orgs/acmecorp/settings` | ❌       | n/a           |

- `/app/:any/orgs/:id`

| URL                             | Matches | `:id` value |
| ------------------------------- | ------- | ----------- |
| `/app/petstore/orgs/org_123`    | ✅       | `org_123`   |
| `/app/dogstore/v2/orgs/org_123` | ❌       | n/a         |

- `/personal-account/(.*)`

| URL                          | Matches |
| ---------------------------- | ------- |
| `/personal-account/settings` | ✅       |
| `/personal-account`          | ❌       |

---

## Sitemap

[Overview of all docs pages](https://clerk.com/docs/llms.txt)
