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

# Cookie-based authentication

> Use a secure, HttpOnly cookie instead of localStorage for Dynamic's JWT — how it works, setup steps, and verification checklist.

Cookie-based authentication configures Dynamic to set a secure, HttpOnly cookie containing a minified JWT instead of returning the token for in-app storage (e.g. localStorage). The browser sends the cookie automatically on same-origin requests, and your app code cannot read or modify it.

This also enables cross-subdomain single sign-on: a user who signs in on one subdomain (e.g. `app.example.io`) is automatically authenticated on other subdomains (e.g. `marketplace.example.io`, `shop.example.io`) that share the same parent domain and Dynamic environment.

## Why use it

* **Reduced XSS risk** — the token is not accessible to JavaScript.
* **Session hijacking mitigation** — HttpOnly cookies cannot be extracted by client-side scripts.
* **Cross-subdomain sessions** — one sign-in covers all subdomains under the same parent domain.

See [Security Best Practices](/overview/security/recommendedpaths) and [Tokens](/overview/authentication/tokens) for more on token storage and security.

## How it works

Dynamic requires a **custom hostname** — a subdomain you own, pointed by DNS CNAME to Dynamic's API. This lets Dynamic's backend set a first-party, secure HttpOnly cookie on your domain.

For example, if your site is `https://app.example.io`, you could configure `https://auth.example.io` as the custom hostname. When a user signs in on `app.example.io`, Dynamic sets an HttpOnly cookie for `.example.io`. That cookie is then sent by the browser on any subdomain ending with `.example.io`.

## Setup

### 1. Create a cookie domain

Go to the Dynamic dashboard, expand **Developer**, and select **Domains**. Create a new [cookie domain](https://app.dynamic.xyz/dashboard/developer/domains).

Provide a subdomain you own. We recommend prefixing with `auth` — for example, `auth.example.io` for the domain `example.io`.

### 2. Configure DNS

Follow the instructions in the dashboard. You will need three DNS records:

* **2 TXT records** — for site and certificate verification.
* **1 CNAME record** — to proxy the custom subdomain to Dynamic.

<Warning>
  Your CAA records must include either `pki.goog` or `letsencrypt.org`. If you use Vercel, see [Vercel's CAA records guide](https://vercel.com/guides/change-caa-records-with-vercel-cname).
</Warning>

<Note>
  In `sandbox`, Dynamic also attempts to set the cookie from the SDK frontend to support local development and preview environments.
</Note>

### 3. Update your SDK configuration

Once DNS is validated, configure your SDK to use the custom hostname as the API base URL. See the SDK-specific guide for your platform:

<CardGroup cols={3}>
  <Card title="React" icon="react" href="/react/authentication-methods/cookie-authentication" />

  <Card title="React Native" icon="react" href="/react-native/authentication-methods/cookie-authentication" />

  <Card title="JavaScript" icon="js" href="/javascript/authentication-methods/cookie-authentication" />
</CardGroup>

### 4. Enable cookie-based authentication

Go to [Account Security](https://app.dynamic.xyz/dashboard/security) in the dashboard and enable the cookie-based authentication toggle.

<Warning>
  When enabled in `live`, Dynamic **will no longer** return a JWT to store in localStorage. The auth token will only be set as a cookie.
</Warning>

The cookie is stored as `DYNAMIC_JWT_TOKEN` in your browser's cookies. It contains the minified Dynamic JWT.

## Verifying your cookie configuration

Before going live, verify your domain and cookie setup.

### Domain configuration

The domain must be set in **both** your sandbox and live environments. The domain you configure must match the verified domain associated with your Dynamic environment — partial or mismatched domains cause cookie-setting to silently fail.

<Warning>
  Cookies cannot be set on `localhost`. Once cookie authentication is enabled on your live environment, you cannot test against it from localhost unless you mask localhost to your live CNAME (e.g. via `/etc/hosts` or a local DNS override).
</Warning>

### Testing locally

For local development, test against the **sandbox environment**. Dynamic includes the JWT in the response header (via localStorage) in sandbox so you can inspect tokens without a valid cookie domain.

<Note>
  The localStorage fallback for JWTs is only available in sandbox. It is not used in production.
</Note>

### Pre-launch checklist

<Steps>
  <Step title="Verify your domain">
    Confirm the domain is set in both your sandbox and live environments in the Dynamic dashboard.
  </Step>

  <Step title="Test on a staging domain">
    Run the full cookie authentication flow on a staging environment with a valid, resolvable domain — not localhost.
  </Step>

  <Step title="Confirm cookie is set">
    Check that the JWT is delivered as a cookie and is not falling back to localStorage.
  </Step>

  <Step title="Enable on live">
    Only enable cookie authentication on your live environment after staging validation passes.
  </Step>
</Steps>
