DNS providers
The 19-provider auto-write fleet, delegated credentials, and Domain Connect.
When a customer's domain is at a supported provider and you've stored a delegated credential, the control-plane writes the DNS records itself — no manual step. Otherwise the flow falls back to guided-manual (copy the records) or Domain Connect (provider-applied template).
Auto-write fleet
These providers have a libdns-shaped writer registered in the adapter registry. Each is idempotent and reconciles full record sets (multi-value rrsets are preserved and stale records removed).
| Provider | Key | Credential |
|---|---|---|
| Cloudflare | cloudflare | Scoped API token (Bearer) |
| DigitalOcean | digitalocean | API token (Bearer) |
| Gandi | gandi | LiveDNS API key |
| deSEC | desec | API token |
| Hetzner | hetzner | DNS API token |
| Vercel | vercel | API token (Bearer) |
| DNSimple | dnsimple | API token (Bearer) |
| Porkbun | porkbun | apikey:secretapikey pair |
| Linode | linode | Personal access token (Bearer) |
| Vultr | vultr | API key (Bearer) |
| Name.com | namecom | user:token (Basic) |
| GoDaddy | godaddy | key:secret (sso-key) |
| IONOS | ionos | API key (prefix.secret) |
| Netlify | netlify | API token (Bearer) |
| Amazon Route 53 | route53 | accessKeyId:secretAccessKey[:region] (SigV4); zone arg = Hosted Zone ID |
| Google Cloud DNS | gcpdns | Service-account JSON (+ managed_zone); OAuth2 JWT → bearer |
| Azure DNS | azuredns | JSON {tenant_id,client_id,client_secret,subscription_id,resource_group}; Entra OAuth2 |
| Namecheap | namecheap | apiUser:apiKey:clientIp (IP must be whitelisted) |
| Domain Connect | domain-connect | Redirect-based (no server token) |
The live set is returned by GET /v1/providers and shown in the console's
Providers view with logos.
Storing a delegated credential
curl -X POST http://localhost:8080/v1/applications/<APP_ID>/credentials \
-H "Authorization: Bearer <YOUR_KEY>" \
-H "Content-Type: application/json" \
-d '{"provider":"cloudflare","token":"<scoped-provider-token>"}'- The token should be scoped to the customer's zone(s) with edit rights.
- It is encrypted at rest (AES-256-GCM) when
CREDENTIAL_ENC_KEYis set; production requires the key (see Security). - Once stored, new
POST /v1/connectionsfor that application auto-write records and skip the manual TXT step — the scoped token is implicit proof of control.
How connecting works — what you need per provider
There are three connection models, with different real-world requirements. "Code ✅" means the adapter is built and tested; the "External" column is what you or your customer must still do — the parts code can't remove.
| Model | Providers | Code | External step |
|---|---|---|---|
| BYO API token | Cloudflare, DigitalOcean, Gandi, deSEC, Hetzner, Vercel, DNSimple, Porkbun, Linode, Vultr, Name.com, GoDaddy, IONOS, Netlify | ✅ | Customer generates a scoped token and pastes it. No approval for most — but GoDaddy gates production API keys by account tier (historically ≥10 domains / reseller), and Namecheap requires enabling API access + IP-whitelisting + an account threshold. |
| Machine credential (OAuth2 / signed) | Google Cloud DNS, Azure DNS, Amazon Route 53 | ✅ | Customer creates a service account (GCP) / app registration (Azure) / IAM key (AWS) in their cloud console and pastes the credential. No approval of your service; the customer needs cloud-admin access. |
3-legged consumer OAuth ("Log in with <provider>, click Allow") | — | ❌ (business step) | You register an OAuth app with each provider and pass their partner/approval process (legal, branding, security review). This is per-provider and cannot be done in code. Domain Connect (below) is the standard alternative that avoids this. |
So: the built adapters are code-complete. Going live as a service means (a) some providers gate who can get API access, and (b) the frictionless "connect account" UX requires per-provider OAuth-app approval that only your company can obtain.
Domain Connect
Domain Connect is redirect-based: the customer is sent to their provider, which
applies a template and returns. There is no server-to-server token. Discovery is
via TXT _domainconnect.<domain> → the provider's settings endpoint. It is the
standard way to offer a smooth connect flow without registering a bespoke
OAuth app per provider.
Roadmap
- Squarespace — no general third-party DNS-record write API; connect via Domain Connect / the guided-manual flow instead of a token adapter.
- Additional libdns providers can be added by implementing a
Writer+ conformance test — see the adapter package README. Per-provider credential creation steps live in Provider setup.