A Caddy DNS module for Sakura Cloud DNS, implementing the libdns interfaces. This enables Caddy to solve ACME DNS-01 challenges via the Sakura Cloud DNS API, which is required for wildcard TLS certificates.
During certificate issuance and renewal, Caddy creates and removes _acme-challenge TXT records automatically via this module.
- Caddy 2.11+ (built with xcaddy)
- A Sakura Cloud API token and secret with read and write access to DNS zones (see Sakura Cloud API key documentation)
xcaddy build --with github.com/kamakiri-labs/caddy-sakuracloud*.example.com {
tls {
dns sakuracloud {
api_token {env.SAKURACLOUD_ACCESS_TOKEN}
api_secret {env.SAKURACLOUD_ACCESS_TOKEN_SECRET}
}
}
# ...
}{
"module": "sakuracloud",
"api_token": "{env.SAKURACLOUD_ACCESS_TOKEN}",
"api_secret": "{env.SAKURACLOUD_ACCESS_TOKEN_SECRET}"
}If api_token or api_secret are not set in the Caddyfile or JSON config, the module falls back to these environment variables. Explicit Caddyfile/JSON values always take precedence.
| Variable | Description |
|---|---|
SAKURACLOUD_ACCESS_TOKEN |
Sakura Cloud API token |
SAKURACLOUD_ACCESS_TOKEN_SECRET |
Sakura Cloud API secret |
These are the same environment variables used by the official sacloud tools.
A, AAAA, ALIAS, CAA, CNAME, HTTPS, MX, NS (read-only), PTR, SVCB, SRV, TXT
NS records are returned by GetRecords but are protected from removal by SetRecords and DeleteRecords to prevent accidental zone breakage.
- Single writer per zone recommended. The module uses optimistic concurrency control (SettingsHash) and per-zone mutexes to handle conflicts, but running multiple Caddy instances managing the same zone is not recommended without external coordination.
- Credential rotation requires process restart. API credentials are captured on first use and cannot be changed without restarting Caddy.
- Zone metadata is cached for the lifetime of the process. If a DNS zone is deleted and recreated externally with the same name, Caddy must be restarted to pick up the new zone ID.
- SDK rate limit. The Sakura Cloud SDK defaults to 5 requests/second.
- Startup API call. On startup or reload, a lightweight API call validates credentials. Failures are logged as warnings and do not block startup, but startup latency is coupled to API response time.
Credentials not working: Verify your API credentials with curl:
curl -s -u "$SAKURACLOUD_ACCESS_TOKEN:$SAKURACLOUD_ACCESS_TOKEN_SECRET" \
https://secure.sakura.ad.jp/cloud/zone/is1a/api/cloud/1.1/commonserviceitemA successful response returns a JSON object with your DNS zones.
Zone not found: Ensure the domain is registered as a DNS zone in your Sakura Cloud account and that the API credentials have access to it.
Update conflict (HTTP 409): This occurs when multiple writers modify the same zone concurrently. The module retries conflicts automatically (up to 3 times with jitter), but persistent conflicts indicate multiple Caddy instances competing for the same zone. Other API errors (auth failures, invalid records, etc.) are not retried and are reported immediately.
Design informed by studying these open source projects:
- caddy-dns/cloudflare and libdns/cloudflare
- libdns/hetzner
- libdns/desec
- KeisukeYamashita/caddy-sakura
Development assisted by Claude Code and Codex.
MIT