Custom domains
Sign people in on a domain you own, such as login.acme.com, as a second issuer of your brand.
A custom domain lets a brand sign people in on a host you own, such as login.acme.com, instead of its own issuer host. It needs a plan that includes custom domains (Pro and up; otherwise plan_feature_unavailable), and a brand has one at most.
Once live, the custom domain is a second issuer of the brand, beside its own. Both have the same users, apps, APIs and signing keys, so a person's sub is the same at both. Each has its own discovery document, its own JWKS address, its own cookies and its own iss in every token. An app moves to the custom domain when you change its issuer URL; apps you don't move keep working on the brand's own issuer, and keep working if the custom domain ever goes.
Adding one
Add a custom domain to a brand with its hostname, or open the brand's Domain tab in the dashboard. Use a subdomain of a domain you own: login.acme.com, never acme.com itself (apex_not_supported), and never one of Synq's own hosts (reserved_hostname). A hostname another brand has proven, or served on in the last 30 days, is hostname_taken. Asking for a hostname holds nothing: until its record proves it, anyone may ask for the same name, and the brand whose record the name points at gets it.
The answer names one DNS record to add where your domain's DNS is managed:
| Type | Name | Value | TTL |
|---|---|---|---|
CNAME | login (the full name is login.acme.com) | cd-… under Synq's domains host, exactly as the answer says | Auto |
The value is made for this domain alone, so the record proves you control the name. Synq checks it on its own (after 1, 2 and 5 minutes, every 15 minutes for the first hour, then hourly); check it now or press Check now to skip the wait. Once the record is there, Synq has a certificate issued for the domain, and the domain goes live, usually within minutes. Your organization's owners and admins get an email when it does. A record that never shows within 7 days fails the domain with verification_expired: remove it, add the record, and add the domain again.
What can be wrong
Read the custom domain to see its status, its record's status (pending, verified or misconfigured, with what was found there instead) and its problems, each with its fix:
| Problem | What to do |
|---|---|
cname_not_found | Add the record, then check again. DNS can take a few minutes to show it. |
cname_points_elsewhere | Change the record to point at the value shown, exactly. |
cname_proxied_by_cloudflare | Your DNS is on Cloudflare and the record is proxied: set its Proxy status to DNS only (the grey cloud). |
conflicting_records | Remove the A, AAAA or TXT records on the same name: a CNAME has to be the only record there. |
caa_blocks_issuance | Your CAA records allow none of the certificate authorities Synq uses: add one allowing letsencrypt.org or pki.goog. |
hostname_taken | Another brand proved the hostname first and still holds it. If it is yours, remove it there, or contact Synq support. |
cloudflare_blocked | The certificate provider refused the hostname. Try another, or contact Synq support. |
certificate_failed | The certificate couldn't be issued in time: check the record and your CAA records, then remove the domain and add it again. |
A domain that fails before it went live no longer holds its hostname, and Synq takes it out of its certificate provider within minutes: fix what its problems say and check it again, and Synq starts over from the record.
Don't use CNAME flattening for the record, and don't put the name behind another CDN: Synq's certificate provider must see the CNAME itself.
Moving an app to it
Once the domain's status is active, its issuer is https://login.acme.com (the brand's custom_domain_issuer says the same). For each app you move:
- Set the app's issuer URL to the custom domain's issuer. The SDKs discover everything else from it.
- If the brand signs in through your own apps at sign-in providers, register the same callback path on the custom domain with each of them, beside the one you have:
https://login.acme.com/federation/<provider>/callback. The dashboard lists them. - Update the APIs that check its tokens: they carry
isshttps://login.acme.com, signed with the same keys, published athttps://login.acme.com/jwks.
A person's session, codes and refresh tokens belong to the issuer that made them: someone signed in on the brand's own host signs in again on the custom domain, as the same user. Their passkeys belong to the host they were made on; in browsers that support related origins (Chrome and Safari), the custom domain's sign-in page also offers the passkeys made on the brand's own host.
Removing one
Remove a brand's custom domain, or remove it from the dashboard behind its typed hostname. It stops answering at once, and every app that signs in with its issuer stops working; the brand's own issuer goes on. Every session, code and refresh token its issuer made ends with it. Apps aren't sent back-channel logouts for those sessions, since the issuer that would sign them is gone: end your apps' own sessions for it when you remove it. You can then delete the DNS record. Removing never needs the plan. Once it has served, the hostname stays reserved for this brand for 30 days: no other brand, in your organization or another, can add it meanwhile.
If your plan changes
When your organization moves to a plan without custom domains, a live domain keeps answering for 14 days. Your owners and admins are emailed at the start, 7 days before and the day before, with the date and what stops working. Move back to a plan with custom domains within those 14 days and it stays; otherwise it is removed when they end. A domain that wasn't live yet is removed at once.
Deleting the brand or the organization removes its custom domain at once. A CNAME that goes missing, or points elsewhere, for 7 days removes the domain too, and you're emailed when it first does.
Every change is in the audit log and can be a webhook: brand.custom_domain_added, .verified, .activated, .failed, .suspended, .restored and .removed.