Custom Domain
This guide walks you through configuring a custom domain for your Descope project so you can manage sessions in cookies on a hostname under your application.
By default, Descope returns session and refresh tokens in the response body, and client SDKs typically store them in local storage. That works fine for getting started, but in production you'll usually want the refresh token in an HttpOnly cookie instead. Refresh tokens are long-lived, and keeping them out of JavaScript helps mitigate XSS attacks.
Because Descope cookies use SameSite=Strict by default, the cookie domain has to be a subdomain of your site — which means you'll need a CNAME pointing at Descope. For more on SameSite and domain scope, see Cross-Site Cookies. For why cookies are the recommended storage approach, see Storing Refresh Tokens.
If you want the broader picture of how Base URLs relate to region (US, EU, AU, CA), custom domains, and private-cloud deployments, see Multi-Region Support.
Note
Configuring a Custom Domain is a Pro+ tier feature.
Learn more about upgrading your tier within our pricing overview.
Configure Custom Domain
Note
Each company has a limit of 10 total number of custom domains across all projects within a company.
If you've reached that limit and need more, contact Descope Support.
The steps below assume your app lives at app.example.com and you are not sharing cookies across multiple subdomains. If you do need to share cookies (for example between app.example.com and docs.example.com), the same flow still applies — you'll just use a different hostname.
See Sharing Cookies Across Multiple Subdomains for those details.
Create a DNS Record
Start by creating a CNAME that maps a hostname you own (for example auth.app.example.com) to Descope's regional target. Pick the row that matches your project's region:
| Region | CNAME target |
|---|---|
| US | cname.descope.com |
| EU | cname.euc1.descope.com |
| AU | cname.aps2.descope.com |
| CA | cname.cac1.descope.com |
A common setup looks like this:
- Name:
auth.app.example.com - Type: CNAME
- TTL: keep the default
- Value: the regional target from the table (for an EU project, that would be
cname.euc1.descope.com)
One thing to keep in mind: this hostname is only for DNS. After verification, you'll point the SDK at your custom HTTPS origin (for example https://auth.app.example.com), not at cname.descope.com.
Note
If you're on a private cloud Descope environment, reach out to your CS manager for the correct CNAME target.

Configure App URL
Next, open Project Settings → General and set App URL to where your application actually lives — for example https://app.example.com.
This is the value Descope uses by default when figuring out cookie domain scope. You only need to change it if your app runs on a different origin than what's already set.

Add and Verify the Custom Domain
Once the App URL is in place, you'll see a Configure Custom Domain section below it. Add the CNAME hostname you created in DNS, then click Refresh until the status shows Setup complete.
When verification finishes, the Console also gives you code snippets for setting baseUrl in your frontend — which is the next step.

Base URL for the Descope SDK
With the domain verified, initialize the Descope SDK with baseUrl set to your custom HTTPS origin — the same hostname you added in DNS (for example https://auth.app.example.com). Don't use the regional cname.*.descope.com target here; that only belongs in DNS.
<AuthProvider projectId="__ProjectID__" baseUrl="https://auth.app.example.com"><descope-wc project-id="__ProjectID__" base-url="https://auth.app.example.com" flow-id="sign-up-or-in"></descope-wc><AuthProvider projectId="__ProjectID__" baseUrl="https://auth.app.example.com">If you also want static assets served from your custom domain instead of static.descope.com, you can set baseStaticUrl as well. See Base URL configuration.
For more background on regional vs custom Base URLs, see Descope Base URLs.
Manage Tokens in Cookies
Now that the domain is ready, you can tell Descope to deliver tokens as cookies. Head to Token Response Methods on the Session Management page, and choose Manage in cookies for the refresh token (and optionally for the session token as well).
Out of the box, Descope uses the defaults below. You usually don't need to change them unless you're running into cookie name conflicts or sharing cookies across subdomains:
| Setting | Default | Where to change it |
|---|---|---|
| Refresh cookie name | DSR | End action in your flow |
| Session cookie name | DS | End action in your flow |
| Cookie domain | Derived from your App URL (for example app.example.com) | Session Management — see also Affected Settings |
SameSite / cookie policy | Project cookie settings | Cross-Site Cookies and Token Response Methods |
Custom cookie names are especially useful when multiple Descope projects share the same root domain and would otherwise both try to write DS / DSR.

Testing Cookie Storage
Note
If you wish to store the cookie values with a different name, you can do so by modifying the End action in your flow.
Once that's configured, run through a login flow and confirm the cookies show up on your app domain. By default you should see DSR (the refresh token) as an HttpOnly cookie. The session token (DS) often remains available to the client unless you've also chosen to manage the session token in cookies.
If you're testing locally against a custom domain and run into cookie issues, see Local Testing Tokens.
OAuth callback domain
After your custom domain is set up, you can use it as the OAuth callback domain too. On each OAuth provider — under Authentication Methods or Tenants — set the callback domain to your custom hostname (for example auth.app.example.com).

Sharing Cookies Across Multiple Subdomains
If you have more than one subdomain that needs to stay logged in together — say app.example.com and docs.example.com — you have two main options. The right choice depends on whether you want cookies shared automatically, or you'd rather keep refresh isolated on an auth host.
Option 1: Cookie domain on example.com
Use this when you want a seamless login experience across every subdomain.
Set the cookie / custom domain scope to example.com instead of a single subdomain like app.example.com. The browser will then send the auth cookies with requests to any host under *.example.com.
Option 2: Cookie domain on auth.example.com
Use this when you want to keep the refresh token off your product subdomains, but still let them refresh sessions.
Store the refresh token only on auth.example.com. Your other apps (app.example.com, docs.example.com, and so on) don't read that cookie directly — they call auth.example.com when they need a new session, and the browser includes the cookie on those requests automatically.
Example settings
Here's how those two approaches look side by side for example.com:
| Setting | Strict (app only) | Shared across subdomains |
|---|---|---|
| CNAME | auth.app.example.com | auth.example.com |
| Cookie domain | app.example.com | example.com |
| Base URL | https://auth.app.example.com | https://auth.example.com |
Affected Settings
When you configure a custom domain, several places in the Console update to match. Most of these are covered in the steps above, but here's a quick rundown of everything that's affected:
- Approved Domains — Domains that are allowed to interact with your Descope project via the SDK and APIs.

- Cookie Domain — The domain scope for cookies that hold the refresh token. This defaults from your App URL; widen it to the parent domain only if you need shared cookies.

- OAuth Callback URL and Callback Domain — The redirect URL and callback domain used during OAuth flows. After you change these in Descope, update the matching values in your OAuth provider (Google, Facebook, and so on).

- Passkey Top-Level Domain — The top-level domain passkeys are associated with.

- Base URL — The host your SDKs and clients use when talking to Descope APIs.

- SAML ACS URL — The Assertion Consumer Service URL in SAML SP configuration for tenants.
