Google Cloud DNS
CertAutoPilot authenticates to Cloud DNS with a service-account key (JSON). The account needs the DNS Administrator role or a narrower custom role restricted to dns.changes.create and dns.resourceRecordSets.* on the managed zone.
Prerequisites
- A GCP project that owns the managed zone (
Cloud DNS → Zones). - Permission to create service accounts + download keys (
iam.serviceAccountKeys.create).
Minimum custom role
For tightest scope, create a role with these permissions, bound to the zone (or the project if zone-level bindings are too granular for your org policy):
dns.changes.create
dns.changes.get
dns.changes.list
dns.managedZones.list
dns.resourceRecordSets.create
dns.resourceRecordSets.delete
dns.resourceRecordSets.list
dns.resourceRecordSets.update
If custom roles are too much ceremony, roles/dns.admin is the stock choice.
Create the service account
gcloud iam service-accounts create certautopilot-dns \
--display-name "CertAutoPilot DNS-01"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member serviceAccount:certautopilot-dns@$PROJECT_ID.iam.gserviceaccount.com \
--role roles/dns.admin
gcloud iam service-accounts keys create sa-key.json \
--iam-account certautopilot-dns@$PROJECT_ID.iam.gserviceaccount.com
The sa-key.json file is the credential you paste into CertAutoPilot. Treat it like a password.
Add the credential
- Settings → DNS Credentials → New → Google Cloud DNS.
- Paste the service-account JSON key directly into the Service account JSON field. The form auto-detects the format.
- Test connectivity → Save.
The form accepts either (a) the raw service-account key JSON as downloaded from GCP, or (b) a wrapped envelope {"project_id": "...", "service_account_json": {...}} where the inner object is the SA key. Use (a) unless your workflow already produces the wrapped form.
Config fields
| Field | Required | Purpose |
|---|---|---|
| Service account JSON | yes | Full JSON key with type: service_account. Envelope encrypted at rest. |
project_id | wrapped only | Set when using the wrapped envelope format. |
zone_id | no | Pin to a specific managed zone when multiple zones share an apex name. |
Propagation
Cloud DNS updates propagate within ~30 seconds globally. The default propagation check works without tuning.
Workload Identity (GKE)
If CertAutoPilot runs in GKE, you can avoid static service-account keys by binding the pod's Kubernetes service account to a GCP service account via Workload Identity. The credential form does not currently accept "no key — use metadata", so you still paste a minted short-lived key for now; full Workload Identity support is on the roadmap.
Troubleshooting
"403 Permission denied"
The service account lacks dns.changes.create on the zone. Grant roles/dns.admin or the custom role above.
"Service account JSON must be a JSON object or string"
The pasted value is neither the raw key nor a valid wrapped envelope. Re-download the key from GCP; don't edit it.
"Quota exceeded" during heavy issuance
Cloud DNS has per-project-per-minute change quotas. Use bulk-action rate limiting (Settings → General) to stay under them.