NamoID public betaBuilding customer authentication? Get setup help and share feedback with other builders.Join the Slack community
NamoID
All posts
NamoID Blog

Custom Authentication Domains: Security, Cookies, and Trust

A hosted sign-in page at project-test.id.example.com can be secure and fully functional. A custom domain such as auth.customer.com adds something different: continuity of trust. The user sees the same organisational domain from the application through authentication, password recovery, and account management.

That trust is valuable, which is exactly why the feature needs more than a CNAME field. A custom authentication domain changes DNS ownership, TLS issuance, request routing, cookies, redirect validation, incident response, and decommissioning.

This guide describes the security model a multi-tenant identity platform should use.

The domain is a security boundary

The browser's origin is the combination of scheme, host, and port. Moving hosted authentication from an identity-provider hostname to https://auth.customer.com creates a new origin and a new cookie boundary.

The desired request path is:

Browser
  │  https://auth.customer.com/sign-in

Customer DNS
  │  CNAME to the identity platform edge

TLS termination
  │  certificate valid for auth.customer.com

Host allowlist and environment resolver
  │  exact verified hostname → one environment

Hosted authentication
  │  host-only secure session cookie

Exact allowlisted application callback

Every arrow needs an ownership or integrity check. DNS alone does not prove that the customer authorised the identity platform to bind the hostname, and a valid certificate alone does not identify which tenant environment should receive the request.

Verify ownership before serving authentication

When a customer enters a domain, create it in an unverified state and generate a high-entropy verification token. Ask the customer to publish that token in a dedicated TXT record, for example:

_namoid-auth.auth.customer.com TXT "verification-token"

The platform should verify the TXT value before it:

  • maps requests for the hostname to the environment;
  • requests or attaches a public TLS certificate;
  • includes the custom issuer in generated configuration;
  • sends users or transactional email links to the hostname.

Use a unique database constraint so the same hostname cannot belong to two environments. Normalise case and reject IP addresses, URLs with paths, ports, wildcards, platform-owned suffixes, and public-suffix entries. The input is a hostname, not an arbitrary URL.

NamoID stores a per-environment verification token, requires the TXT challenge, and resolves only verified custom domains. The verified hostname becomes that environment's canonical issuer host.

Keep verification and traffic records separate

The ownership TXT record and traffic CNAME solve different problems:

  • TXT: proves control of the DNS zone during enrolment and re-verification.
  • CNAME or equivalent: directs browser traffic to the identity edge.

Do not mark the domain ready merely because the CNAME resolves. An attacker or mistaken operator may be able to point a hostname without having the authority expected by your onboarding process. Likewise, a correct TXT record does not mean traffic or TLS is ready.

Expose these states separately in the console:

unconfigured → awaiting verification → verified → TLS provisioning → active
                                                   └──────────────→ failed

Give the customer the exact record name, value, target, observed result, and next action. DNS propagation is eventually consistent; retries should be safe and should not issue duplicate bindings.

TLS must be automated and observable

Authentication must never fall back to HTTP. Provision a certificate only after ownership validation, serve the hostname with TLS 1.2 or later, and redirect port 80 to HTTPS without processing credentials there.

Monitor:

  • certificate issuance and renewal state;
  • certificate expiry horizon;
  • unexpected Certificate Transparency entries;
  • CAA failures where customers restrict certificate authorities;
  • DNS target changes;
  • TLS hostname mismatch and edge routing errors.

Certificate renewal is also an ownership-lifecycle signal. Do not rely on renewal failure as the first indication that a customer removed their DNS records; by then users may already be locked out.

Resolve hosts by exact verified mapping

The incoming Host header decides which environment's branding, sign-in methods, users, keys, and policies apply. That makes host resolution an authorisation boundary.

Use an exact, indexed lookup:

verified hostname → environment_id → project_id → tenant_id

Reject unknown hosts with a human-safe page. Never fall back to a default tenant, infer an environment from a substring, or trust a tenant or project ID supplied in a browser query parameter. Validate forwarded host headers only from a trusted reverse proxy and configure that proxy to replace, rather than append untrusted values.

The same host must drive the issuer URL used in tokens and discovery documents. If the browser signs in at auth.customer.com but receives tokens claiming an unrelated issuer, standards-based clients will reject them, and clients that do not reject them are vulnerable to issuer confusion.

Use host-only cookies

The session cookie for auth.customer.com should belong to that host alone. Do not set Domain=customer.com simply because the customer owns the parent domain.

OWASP's session management guidance recommends omitting the Domain attribute so the cookie is restricted to the origin host. A broad parent-domain cookie is sent to sibling hosts, increasing exposure to a vulnerable marketing site, forgotten subdomain, or takeover.

Use:

  • Secure so the browser sends it only over HTTPS;
  • HttpOnly so application JavaScript cannot read it;
  • an intentional SameSite policy matching the sign-in flow;
  • Path=/ for a host-wide authentication session;
  • short, server-enforced expiry and revocation;
  • the __Host- prefix where deployment constraints permit it.

MDN documents that a __Host- cookie must be Secure, use Path=/, and omit Domain, binding it as closely as possible to the host origin.

Do not try to share the hosted-auth cookie with the customer application. The application should establish its own session through a secure callback or backend exchange. Separate cookies limit the impact if either origin is compromised.

Custom domains do not remove redirect validation

A branded authentication origin and an application callback are different trust decisions. Continue to require exact allowlisted callback and logout URLs.

Avoid:

  • wildcard callbacks such as https://*.customer.com/callback;
  • prefix matching;
  • arbitrary return_to values;
  • trusting a callback because it shares the parent domain;
  • carrying tokens in query strings.

A compromised sibling subdomain should not become a valid recipient for authentication results. Exact redirect matching remains necessary even when every hostname looks familiar.

Apply the same discipline to CORS, Content Security Policy, post-logout redirects, email links, and passkey relying-party configuration. A custom domain feature is incomplete if only the sign-in page knows the new host.

Passkeys require deliberate domain planning

WebAuthn credentials are scoped to a relying-party ID. A passkey registered for one domain cannot be casually moved to an unrelated domain later.

Before enabling passkeys, decide whether the RP ID is:

  • the exact custom authentication host; or
  • a registrable parent domain intentionally shared by a controlled set of subdomains.

The exact host gives the narrowest boundary. A parent RP ID can support flows across subdomains, but it expands the trust surface and requires each participating origin to be tightly controlled. Never derive the RP ID from an unverified request header.

Changing or removing a custom domain may strand passkeys registered under its RP ID. The console should warn customers before activation and decommissioning, and the product should provide another authenticator for account recovery.

Re-verify ownership continuously

Ownership can change after setup. A customer may delete the TXT record, repoint the CNAME, lose the domain, or move DNS providers.

NamoID periodically rechecks verified-domain TXT challenges and emits an audit event when re-verification fails. A single DNS lookup failure should not instantly disable sign-in because transient DNS failures happen. Instead:

  1. record the failed check;
  2. retry over a defined grace window;
  3. notify tenant managers;
  4. escalate persistent mismatch;
  5. disable the mapping before an ownership loss becomes exploitable.

Monitor the traffic record as well as the TXT challenge. A healthy TXT record with a CNAME pointing elsewhere can still break sign-in or expose users to unexpected content.

Prevent dangling-domain takeover

OWASP's subdomain takeover guidance describes the classic failure: DNS continues pointing at a third-party resource after that resource has been deleted, allowing someone else to claim it.

For authentication domains, the impact can include phishing on a trusted hostname, theft of broadly scoped cookies, abuse of allowlisted callbacks, and unexpected certificate issuance.

Use a safe removal order:

  1. Stop issuing new authentication transactions for the custom hostname.
  2. Move users and configured application links to the platform hostname or replacement domain.
  3. Remove the hostname from callback, CORS, CSP, passkey, and email configuration.
  4. Ask the customer to remove or replace the DNS records.
  5. Wait at least the DNS TTL and verify the old mapping no longer reaches the service.
  6. Remove the edge binding and certificate association.
  7. Retain a minimal audit event for the change.

Do not delete the hosting resource first while leaving customer DNS pointed at a claimable name.

Test more than the happy path

A custom-domain release checklist should include:

  • duplicate-domain registration across tenants;
  • incorrect, missing, and stale TXT values;
  • CNAME success with TXT failure and the reverse;
  • unknown and spoofed Host headers;
  • certificate issuance and renewal failure;
  • exact issuer and discovery URLs;
  • cookie Domain, Secure, HttpOnly, SameSite, Path, and expiry attributes;
  • callback and logout allowlist rejection;
  • passkey registration and authentication on the final RP ID;
  • DNS removal, re-verification failure, grace period, and disablement;
  • deletion without a dangling provider resource;
  • audit events for set, verify, failure, and clear operations.

Run browser tests from outside your internal network. Local DNS, cached certificates, and proxy headers can conceal the failures real users will encounter.

Trust comes from lifecycle discipline

The visible benefit of a custom authentication domain is branding. The underlying value is a consistent origin users can recognise and security teams can govern.

That value exists only when the platform proves ownership, automates TLS, maps the host to exactly one environment, limits cookies to that host, validates every redirect, re-verifies DNS, and decommissions the domain without leaving a claimable record.

NamoID supports environment-scoped custom authentication domains alongside its generated hosted-auth domains. Create a NamoID account to configure authentication in Test before attaching a production hostname.

Related posts