DNS and domains
Configuring DNS for an Olympus production deployment
Olympus needs three subdomains of a domain you control:
| Subdomain | Purpose |
|---|---|
ciam.<your-domain> | CIAM Hera login UI + CIAM Hydra OAuth2 endpoints |
iam.<your-domain> | IAM Hera login UI + IAM Hydra OAuth2 endpoints |
<your-domain> or app.<your-domain> | The Site (brochure + docs) and your application |
Each is an A record pointing at your VPS's public IP (or a Reserved IP / Load Balancer if you have one).
DNS records
ciam.example.com A 203.0.113.10
iam.example.com A 203.0.113.10
www.example.com A 203.0.113.10
example.com A 203.0.113.10If you have IPv6 on the VPS, add matching AAAA records.
If you're using Cloudflare in front of Olympus (recommended for DDoS protection), set the records as DNS-only (grey cloud) initially, Cloudflare's orange-cloud proxy intercepts TLS and breaks Let's Encrypt's HTTP-01 challenge. Switch to orange-cloud after the first cert is issued (use DNS-01 instead, see below).
TLS via Let's Encrypt
Caddy handles TLS automatically. On first start:
- Caddy attempts the HTTP-01 challenge: it spins up a temporary handler at
http://<domain>/.well-known/acme-challenge/..., Let's Encrypt fetches it, validates, and issues the cert. - Cert is stored in
/data/caddy/certificates/. - Caddy renews 30 days before expiry, automatically.
For DNS-01 (required behind Cloudflare's proxy):
- Issue a Cloudflare API token with
Zone.DNS.Editfor your domain. - Set
CADDY_CLOUDFLARE_API_TOKENin the deployment env. - The Caddyfile is preconfigured to use DNS-01 when the env var is present.
Three-zone propagation timing
When you update DNS records, allow up to 48 hours for full propagation (most updates are under 1 hour but some resolvers cache for the TTL of the previous record). For a quick test:
dig ciam.example.com
dig iam.example.com
# Expected: A record pointing at your VPS IPWildcard certs (alternative)
If you want a single wildcard cert for *.example.com instead of three separate certs:
- Use DNS-01 (HTTP-01 doesn't support wildcards).
- Configure Caddy with:
*.example.com { tls { dns cloudflare {env.CADDY_CLOUDFLARE_API_TOKEN} } }
Wildcard certs work but make the per-subdomain Caddy config more complex. Three separate certs is simpler.
Internal-only deployment
If Olympus is only reachable from a private network (Tailscale, VPN, etc.), DNS can point at private IPs:
ciam.example.com A 10.0.0.5For TLS, use DNS-01 with a public domain, Let's Encrypt validates ownership of the public domain regardless of where the actual host IP routes. Or use mkcert / your own internal CA.
Subdomain takeover risk
If you stop pointing a subdomain at your VPS but leave the DNS record, an attacker could claim the IP (cloud providers recycle IPs). This is "subdomain takeover."
Mitigation:
- Delete DNS records as soon as you decommission a subdomain.
- Monitor Certificate Transparency logs for cert issuance under your domain (services like Cert Spotter alert on unexpected certs).
Cookie domain configuration
Once DNS is set, configure Kratos's cookie domain to match. In kratos.yml:
session:
cookie:
domain: example.com # parent, cookies visible to ciam.example.com and iam.example.com
same_site: Lax
path: /But note: Olympus's CIAM/IAM isolation wants different cookie domains for CIAM and IAM. The correct config is:
# CIAM kratos.yml
session.cookie.domain: ciam.example.com
# IAM kratos.yml
session.cookie.domain: iam.example.comThis ensures a CIAM session cookie can't be sent to IAM and vice versa.