v1.3.0-alpha — 2026-04-21¶
First alpha of the DNS providers expansion. Backend-only — no UI yet. Dogfood via curl against /api/dns-providers; the Settings page lands in sub-phase B.
What landed¶
New: Route 53 as a native DNS-01 provider¶
The Caddy image now ships with both caddy-dns/cloudflare (unchanged) and caddy-dns/route53 (new) compiled in. Hosts that set tls_challenge='dns' can pick either by populating the new tls_dns_provider field on the host.
Panel-managed credentials (encrypted at rest)¶
Pre-v1.3, the Cloudflare token lived in .env and was read at runtime by the caddy container via the {env.CLOUDFLARE_API_TOKEN} placeholder. In v1.3 the panel owns the credentials: a new dns_providers table stores them AES-GCM-encrypted under the existing ARGOS_MASTER_KEY, and the reconciler decrypts + inlines them into the /load JSON on every push (Option 2 in docs/internals/dns-providers-analysis.md).
Upshot: credential rotation is hot. Save via API → reconcile → new creds are active. No container restart.
Boot-time import from the legacy env var¶
On first boot after upgrade, if CLOUDFLARE_API_TOKEN is set in the panel's environment and the dns_providers.cloudflare row has no credentials yet, the env value is encrypted into the DB and the row is flipped enabled. Idempotent on subsequent boots; emits a one-time INFO log advising the operator to remove the env value from .env. The env var continues to work as a fallback for one release and is slated for removal in v1.4.
New API endpoints¶
All three are session-authed (same middleware as every other admin endpoint):
GET /api/dns-providers— lists the catalogue plus DB state (enabled + configured flags + updated_at). Credentials are never returned.GET /api/dns-providers/{name}— single provider.PUT /api/dns-providers/{name}— body{enabled, credentials}. Validates required fields per the catalogue; supports the__UNCHANGED__sentinel for per-field rotation. Triggers a reconcile automatically on success.
See DNS providers for full curl examples.
Host model change¶
New column hosts.tls_dns_provider, default 'cloudflare'. Existing rows are backfilled by migration 025. The Host API accepts the new field on POST/PUT; it is validated against the catalogue and rejects a value whose corresponding dns_providers row is disabled or missing credentials (with a legacy fallback when the token lives in CLOUDFLARE_API_TOKEN).
Migrations¶
- 024 —
dns_providerstable with seeded rows for cloudflare + route53 (bothenabled=0by default). - 025 —
ALTER TABLE hosts ADD COLUMN tls_dns_provider TEXT NOT NULL DEFAULT 'cloudflare'.
Both are plain SQL; down paths drop the column / table respectively. A TestRollbackLastMigration in the db package now exercises the full 025→024→023 rollback sequence.
What's NOT in this alpha¶
- Settings UI for DNS providers — sub-phase B.
- Host form dropdown for picking a provider when challenge=DNS — sub-phase B.
- Test-connection button — deferred to v1.3.x.
- Tier 2 providers (gandi, desec, ovh, duckdns, porkbun, hetzner, digitalocean, acmedns) — sub-phase C.
- Namecheap — excluded from the roadmap until upstream adds a LICENSE file; tracked in the analysis doc.
Upgrade path¶
- Migrations 024/025 run automatically on panel startup.
- Legacy
CLOUDFLARE_API_TOKENfrom.envis imported on first boot; you do not need to act immediately. Watch for thedns_provider: imported CLOUDFLARE_API_TOKEN ...INFO line in the panel log. - Your existing DNS-01 hosts keep working: every row now reads
tls_dns_provider='cloudflare'thanks to the default.
Rollback path¶
# From backend/cmd/argos: migrate-down runs one step at a time.
argos --migrate-down # removes 025: hosts.tls_dns_provider column
argos --migrate-down # removes 024: dns_providers table
# Redeploy v1.2 image if needed. CLOUDFLARE_API_TOKEN in .env still
# takes effect for the v1.2 generator.
Related¶
- DNS providers — feature reference with API examples.
dns-providers-analysis.md— full scoping doc (not published in the portal) explaining the Tier 1 / Tier 2 split and the Option 2 pipeline decision.- Manual DNS workflow — the acme.sh fallback path for providers not in the catalogue. Still supported and still the right answer for long-tail providers.