# Custom domains

> Serve sign-in from your own domain, such as login.example.com, with automatic TLS.

Source: https://9in.io/docs/custom-domains/

Serve sign-in from your own domain, such as `login.acme.com`. Users trust a sign-in page on your domain more, password managers match it to your product, and 9in's cookies are first-party for your site.

## Add a domain

1. **Custom Domains → Add domain**: enter the hostname, e.g. `login.acme.com`.
2. At your DNS provider, add the record the console shows:

   | Type | Name | Value |
   |---|---|---|
   | CNAME | `login.acme.com` | `cname.9in.io` |

   The console may also show an optional TXT record that proves ownership before you switch the CNAME, so there's no gap when you move a hostname that is already in use.
3. Wait for **Active**. 9in checks every 5 minutes; the certificate is issued and renewed automatically.

The number of custom domains depends on your plan.

## What changes

- The **issuer** for requests on that host is `https://login.acme.com`: tokens issued there have `iss: https://login.acme.com`, and discovery is at `https://login.acme.com/.well-known/openid-configuration`. Point your apps at it, and verify tokens with that issuer.
- The `*.9in.io` hostnames keep working, with their own issuer. A token's `iss` is the host it was issued on, so don't mix them in one app.
- Users, sessions and keys are the same on every hostname of the tenant.

## Update your configuration

- **Social and enterprise providers using your own OAuth apps:** add `https://login.acme.com/oauth/social/callback` and `https://login.acme.com/oauth/enterprise/callback` to the redirect URIs there.
- **Bot protection:** Turnstile checks hostnames, so custom domains need your own Turnstile widget (site key and secret key, **Security → Bot protection**).
- **Your apps:** use the new issuer, and add the new logout and callback URLs if they changed.
