Issue an ACME Wildcard Certificate
Get a Let's Encrypt wildcard certificate (*.acme.example) using DNS-01 challenges. Wildcards require DNS-01 — Let's Encrypt won't sign one via HTTP-01. ScaiVault handles the DNS dance automatically once you've connected a DNS provider.
What you need#
- A domain whose authoritative nameservers you control (or that's hosted on a supported DNS provider).
- A ScaiVault token with
pki:issueandpki:admin. - A reachable HTTPS endpoint for renewal-status webhooks (optional but recommended).
1. Configure a DNS provider#
ScaiVault writes the _acme-challenge TXT record via this provider during the challenge. Use whichever your zone lives on; this example uses Route 53.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
The IAM credentials need a minimum policy — see DNS Providers Reference. The verify: true flag refuses to create the provider if it can't list zones, so you'll know immediately if the credentials are wrong.
2. Register an ACME account#
Use the staging environment for your first attempt — Let's Encrypt's staging server has looser rate limits and you don't want to burn through your production quota debugging signatures.
1 2 3 4 5 6 7 8 9 10 | |
ScaiVault generates the ACME account key and registers with Let's Encrypt. The account key stays in ScaiVault.
3. Issue a wildcard cert (staging)#
1 2 3 4 5 6 7 8 9 10 | |
Including the apex acme.example alongside *.acme.example is common — wildcards don't match the apex, so cover it explicitly if you want both.
Poll:
1 2 3 4 5 6 7 8 | |
Typical sequence:
pending(~5s) — ScaiVault writes the TXT record.pending(~30-60s) — waiting for DNS propagation.processing(~5s) — telling ACME the challenge is ready.valid— done. The cert is issued.
Get the certificate:
1 2 3 4 5 6 7 | |
The cert chains back to Let's Encrypt's staging root — your browser will reject it as untrusted. That's expected; staging certs are intentionally not trusted by public roots.
4. Promote to production#
Repeat steps 2 and 3 with environment: "production". Same code, real cert.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Watch out for Let's Encrypt's rate limits — 50 certs per registered domain per week. If you're testing in production and hit this, switch back to staging.
5. Get the cert into your edge#
For an ingress (nginx, Traefik, HAProxy) running in Kubernetes, fetch the cert at startup and refresh periodically. A small init script and CronJob:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Run this on a CronJob every 6 hours. Idempotent — same cert, no-op reload. When the underlying cert renews (~30 days before expiry), the next CronJob run picks up the new version and triggers a reload.
6. Auto-renewal verification#
auto_renew: true means ScaiVault will renew automatically ~30 days before not_after. Subscribe to certificate.renewed events so you can confirm the renewal worked and your edge has refreshed:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Alert on certificate.renewal_failed. ScaiVault retries on backoff, but persistent failures (DNS provider creds expired, Let's Encrypt rate-limit hit) need human intervention.
7. Force an early renewal (rare)#
If you need to renew before the 30-day window — e.g., emergency rotation, an audit requirement — trigger it:
1 2 | |
Same ACME flow, new cert issued. Watch out: every renewal counts against the Let's Encrypt rate limit.
What you have now#
- A wildcard cert covering
*.acme.exampleandacme.example. - Auto-renewal ~30 days before expiry, with event notification.
- A DNS provider configured to handle challenges for the zone.
- Edge servers reloading the cert without manual intervention.
Common failure modes#
Order stays pending for minutes. DNS propagation is slow. Check authoritative nameservers directly: dig +short TXT _acme-challenge.acme.example @<authoritative-ns>. If the record isn't there, your DNS provider integration didn't write it — check the provider with POST /v1/dns/providers/{id}/verify and the audit log for dns_record_create.
Order goes invalid quickly. Look at the order's challenges[].error field. Common: domain in the order isn't in any DNS provider's managed_zones. Add the zone to a provider.
Rate-limit error from Let's Encrypt. Switch back to staging, or wait. The error envelope tells you when you can retry: "backend_rate_limited" with "retry_after".
Wildcard doesn't work for the apex. *.acme.example doesn't match acme.example. Include both in domains, as in step 3.
What's next#
- PKI guide — internal CA hierarchy and mTLS.
- DNS Providers reference — every supported provider's config.
- Webhook Signatures — signing details for the renewal subscription.