Set up a custom login domain
A custom domain such as login.acme.com serves every end-user surface of your environment: hosted login, the account portal, the Admin Portal, the OIDC and OAuth endpoints, SSO, SAML and SCIM, and the links in emails. Your own application's domain is not hosted by KeenAuth. The development environment has no custom domains.
Before you start
- The name must have at least three labels (a subdomain), because a CNAME cannot be set at the root of a domain.
- It is converted to its IDNA2008 A-label and lowercased. It cannot be
keenauth.app,keenauth.comor a subdomain of them, and it cannot be a public suffix. - A name is unique across the platform. A released name is held in quarantine for 30 days before another account can add it.
- Free plan: one domain, and the account must have a verified payment card. More than one domain per environment is an Enterprise feature.
- Each account can add at most 10 domains per day (UTC). Rejected attempts count too.
Step 1: add the domain
Call Add a custom domain. The domain starts in pending_dns and the response lists the DNS records to publish.
Step 2: publish two DNS records
| Type | Name | Value |
|---|---|---|
| TXT | _akp-verify.<hostname> |
idp-verify=<26-character base32 token> |
| CNAME | <hostname> |
<environment-slug>.<region>.edge.keenauth.app |
Keep the TXT record in DNS permanently, also after the domain is active. It is the proof of ownership: if the domain changes hands, the previous owner can no longer have the page served.
Both records must be visible. The check runs every 5 minutes for 72 hours, then hourly for 30 days. To restart a stopped check, call Verify a custom domain.
Step 3: check CAA records
If the domain or any parent domain has a CAA record, it must allow both ACME certificate authorities that KeenAuth uses. Otherwise the domain returns to pending_dns with the failure reason caa_blocked, and the dashboard shows the exact CAA line to add. If no CAA record exists, nothing is needed.
Certificate and lifecycle
KeenAuth obtains and renews the TLS certificate for you. A certificate is renewed when less than 30 days of its life remain. If renewal fails for 7 days you get the custom_domain.certificate_renewal_failed event and an email. Event delivery is not available yet; it comes with webhooks in Phase 6A.
| Status | Meaning | Next |
|---|---|---|
pending_dns |
Added; waiting for the TXT and CNAME records | Both seen: issuing |
issuing |
Certificate is being issued | Issued: active. CAA block: pending_dns with caa_blocked. Not issued within 72 hours: pending_dns with certificate_failed |
active |
In service | A failed daily check: degraded |
degraded |
The TXT or CNAME record has been missing for a day or more; the domain still serves | Fixed: active. Not fixed for 7 days: disabled |
disabled |
Out of service; the certificate is deleted and sessions on this host are invalidated | You restart with :verify: pending_dns |
released |
The domain or the environment was deleted | After 30 days of quarantine the name can be added again |
An active domain is checked once every 24 hours. Subscribe to the events custom_domain.verified, custom_domain.activated, custom_domain.degraded and custom_domain.disabled to be told when something changes. These events are not available yet; delivery comes with webhooks and the event API in Phase 6A.
Primary domain and removal
One domain of the environment is primary; email links use it. Change it with Make a custom domain primary. When the environment's issuer follows the primary domain, changing the primary domain changes the issuer and is a planned operation scheduled at least 7 days ahead.
A primary domain, or the domain that is the issuer, cannot be deleted (409 custom_domain_in_use). Choose another primary domain first. A domain used as a passkey rpId cannot be deleted or disabled either (409 domain_in_use_by_rp_id).
Several domains in one environment
On Enterprise an environment can have several verified domains. Each domain has its own session cookie, so there is no silent SSO between domains. Passkeys across domains depend on the rpId choice and on the related origins list, which holds at most 5 registered-domain labels and only active domains of the same environment. Each application can have its own branding on every domain; see Brand your login pages.