From 3aa1aabba32c2c40832bf9548b05a9e816f9dd9f Mon Sep 17 00:00:00 2001 From: cpln docs publisher Date: Sun, 25 Oct 2026 16:57:00 +0000 Subject: [PATCH] certificate generator: document the cpln dns01 provider (delegated _acme-challenge) --- llms.txt | 4 +-- reference/certificategenerator.mdx | 54 ++++++++++++++++++++++++++---- reference/domain.mdx | 20 +++++------ skill.md | 2 +- 4 files changed, 61 insertions(+), 19 deletions(-) diff --git a/llms.txt b/llms.txt index 7e4ee9cd..5541edc2 100644 --- a/llms.txt +++ b/llms.txt @@ -203,7 +203,7 @@ Two DNS modes: |:---|:---| | `dnsMode` | `cname` or `ns`. **Apex domains MUST use `cname`** — NS does not support apex | | `certChallengeType` | `http01` or `dns01`. **NS mode requires `dns01`** (`http01` rejected) | -| `certificateGeneratorLink` | Issue certs from a custom ACME CA via a [certificate generator](https://docs.controlplane.com/reference/certificategenerator). **Must not** be combined with `certChallengeType` or `tls.serverCertificate`; an `http01` generator is rejected with `dnsMode: ns`, `gvcLink`, or `workloadLink` | +| `certificateGeneratorLink` | Issue certs from a custom ACME CA via a [certificate generator](https://docs.controlplane.com/reference/certificategenerator). **Must not** be combined with `certChallengeType` or `tls.serverCertificate`; an `http01` generator is rejected with `dnsMode: ns`, `gvcLink`, or `workloadLink`. A `dns01` generator with provider `cpln` (the default, `dns01: {}`) needs the `_acme-challenge` CNAME like built-in `dns01`; credentialed providers need none | | `gvcLink` ⊻ `workloadLink` ⊻ `ports.routes` | Mutually exclusive. `workloadLink` (replica-direct) is **Stateful only** | | `acceptAllHosts` ⊻ `acceptAllSubdomains` | Mutually exclusive; both require dedicated LB | | `ports[].protocol` | `http`, `http2` (default), `tcp` (`tcp` requires dedicated LB) | @@ -382,7 +382,7 @@ cpln logs '{gvc="GVC", workload="WL"}' --org ORG --tail - [Agent](https://docs.controlplane.com/reference/agent): Wormhole agents for secure connectivity to private networks, VPCs, and on-prem resources - [Audit Context](https://docs.controlplane.com/reference/auditctx): Audit context configuration for scoping audit trail queries - [Billing API](https://docs.controlplane.com/reference/billing-api): billing-ng.cpln.io endpoints: account and org charge queries priced by rate plan, account-wide tag values, chargeable items, invoices (JSON/PDF, amounts in cents), the monthly spend alert, billing service account tokens (cpln-bsat-), listing and creating the account's orgs, billing users, invoice email recipients, and which billing role or org permission each requires -- [Certificate Generator](https://docs.controlplane.com/reference/certificategenerator): Custom ACME certificate authority for domain certificates, with HTTP-01 or DNS-01 (Route53, Cloud DNS, Azure DNS, Cloudflare) challenges and external account binding +- [Certificate Generator](https://docs.controlplane.com/reference/certificategenerator): Custom ACME certificate authority for domain certificates, with HTTP-01 or DNS-01 challenges (delegated to Control Plane via an `_acme-challenge` CNAME, or written with Route53, Cloud DNS, Azure DNS, or Cloudflare credentials) and external account binding - [Cloud Account](https://docs.controlplane.com/reference/cloudaccount): Cloud provider account mappings that work with identities to enable credential-free cloud resource access via Universal Cloud Identity - [Deployment](https://docs.controlplane.com/reference/deployment): The read-only observed state of one workload in one location: endpoints, versions and their per-container readiness, restarts and exit codes, cron job execution history, how to read a rollout, and the 45-minute stale / 24-hour expiry rules - [Domain](https://docs.controlplane.com/reference/domain): Custom domain configuration with TLS, geo-routing, path-based and subdomain-based DNS modes, required client certificates (mTLS), and private .internal domains diff --git a/reference/certificategenerator.mdx b/reference/certificategenerator.mdx index c895b2ed..be082e85 100644 --- a/reference/certificategenerator.mdx +++ b/reference/certificategenerator.mdx @@ -1,7 +1,7 @@ --- title: Certificate Generator -description: Issue domain TLS certificates from your own ACME certificate authority, solving HTTP-01 or DNS-01 challenges in DNS zones you control. -keywords: ['custom ca', 'sectigo', 'zerossl', 'external account binding', 'eab', 'route53', 'cloud dns', 'azure dns', 'cloudflare', 'wildcard cert', 'cert-manager', 'lets encrypt alternative'] +description: Issue domain TLS certificates from your own ACME certificate authority, solving HTTP-01 or DNS-01 challenges either delegated to Control Plane or in DNS zones you control. +keywords: ['custom ca', 'sectigo', 'zerossl', 'external account binding', 'eab', 'route53', 'cloud dns', 'azure dns', 'cloudflare', 'wildcard cert', 'cert-manager', 'lets encrypt alternative', 'acme challenge cname', 'dns delegation'] --- ## Overview @@ -22,7 +22,7 @@ The only supported provider is `acme`. | `spec.acme.externalAccountBinding` | No | Binds the ACME account to an existing account at the CA. Most commercial CAs require it. See [External account binding](#external-account-binding). | | `spec.acme.challenge` | Yes | Exactly one of `http01` or `dns01`. The challenge type cannot be changed after creation. | -The provider, server, and challenge type identify the ACME account. To change any of them, create a new certificate generator and point your domains at it. +`spec.provider`, `spec.acme.server`, and the challenge type identify the ACME account. To change any of them, create a new certificate generator and point your domains at it. ### Challenge types @@ -48,7 +48,31 @@ challenge: #### DNS-01 -The CA validates the domain through a TXT record that Control Plane writes into your DNS zone, using credentials you provide in a [secret](/reference/secret). Set `provider` and the matching block: +The CA validates the domain through a TXT record at `_acme-challenge.`. The `provider` decides where Control Plane writes that record: + +- `cpln` (the default): in Control Plane's own DNS. Each domain delegates the record with one CNAME. No credentials are needed. +- `route53`, `cloudDns`, `azureDns`, or `cloudflare`: in your DNS zone, using credentials you provide in a [secret](/reference/secret). + +**Delegated to Control Plane (`cpln`)** + +```yaml +challenge: + dns01: {} # same as dns01: { provider: cpln } +``` + +`cpln` takes no other settings. Each CNAME-mode domain that uses the generator needs this record, which is also listed in the domain's [`status.dnsConfig`](/reference/domain#dns-configuration-records): + +| Host | TTL | Type | Value | +| :--- | :-- | :--- | :--- | +| `_acme-challenge.` | 300 | CNAME | `_acme-challenge.cpln.app` | + +It is the same record the built-in `dns01` challenge uses, so a domain moving from the built-in challenge to a `cpln` generator keeps it. Domains with `dnsMode: ns` need no extra record, except [replica-direct](/reference/domain#replica-direct-routing) domains (`workloadLink`), which always need it. + +Your CA must follow the CNAME when it looks up the TXT record. Most public CAs do; confirm with yours. + +**In your own DNS zone** + +Set `provider` and the matching block: | `provider` | Settings | Secret type | Required access | | :--- | :--- | :--- | :--- | @@ -61,7 +85,9 @@ The CA validates the domain through a TXT record that Control Plane writes into - For `route53`, if the `aws` secret sets `roleArn`, that role is assumed before records are changed. - `azureDns` supports the Azure public cloud only. -Because Control Plane writes the challenge record into your own zone, a CNAME-mode domain using a `dns01` generator does not need the `_acme-challenge` CNAME record that the built-in `dns01` challenge requires. When switching a domain from the built-in `dns01` challenge to a generator, delete that CNAME record: a TXT record cannot be created at a name that already has a CNAME. +Because Control Plane writes the challenge record into your own zone, domains using these providers do not need the `_acme-challenge` CNAME record. When switching a domain from the built-in `dns01` challenge or a `cpln` generator to one of these providers, delete that CNAME record: a TXT record cannot be created at a name that already has a CNAME. + +`dns01.provider` and its settings can be changed after creation, unlike `spec.provider`, `spec.acme.server`, and the challenge type. Re-apply the full generator with `cpln apply` so the previous provider's block is removed. The records each domain needs change with it, as listed in the domain's `status.dnsConfig`. ### External account binding @@ -134,7 +160,23 @@ A DNS-01 generator for a commercial CA, with credentials for Route53: -Create it with [`cpln apply`](/guides/cpln-apply): +A DNS-01 generator that delegates to Control Plane needs no DNS credentials: + +```yaml +kind: certificategenerator +name: corporate-ca-delegated +spec: + provider: acme + acme: + server: https://acme.example-ca.com/directory + externalAccountBinding: + keyId: KEY_ID_FROM_CA + secretLink: //secret/acme-eab-hmac + challenge: + dns01: {} +``` + +Create a generator with [`cpln apply`](/guides/cpln-apply): ```bash cpln apply --file certificate-generator.yaml diff --git a/reference/domain.mdx b/reference/domain.mdx index 872ea973..be7f7b4c 100644 --- a/reference/domain.mdx +++ b/reference/domain.mdx @@ -339,7 +339,7 @@ When a `gvcLink` is configured, each workload in the GVC is served at `.cpln.app" }, { - "type": "TXT", + "type": "CNAME", "ttl": 300, - "host": "_acme-challenge.sub.example.com", - "value": "challenge-token-value" + "host": "_acme-challenge.sub", + "value": "_acme-challenge.cpln.app" } ] } diff --git a/skill.md b/skill.md index 65afd5f7..8bf9f196 100644 --- a/skill.md +++ b/skill.md @@ -521,7 +521,7 @@ Provider sections each have XOR rules (e.g. AWS `roleName` ⊻ `policyRefs`; GCP | --- | --- | | `dnsMode` | `cname` or `ns`. **Apex domains MUST use `cname`** — NS doesn't support apex. | | `certChallengeType` | `http01` or `dns01`. **NS mode requires `dns01`** (`http01` rejected). | -| `certificateGeneratorLink` | Custom ACME CA via a [certificate generator](https://docs.controlplane.com/reference/certificategenerator). **Must not** be combined with `certChallengeType` or `tls.serverCertificate`; an `http01` generator is rejected with `dnsMode: ns`, `gvcLink`, or `workloadLink`. | +| `certificateGeneratorLink` | Custom ACME CA via a [certificate generator](https://docs.controlplane.com/reference/certificategenerator). **Must not** be combined with `certChallengeType` or `tls.serverCertificate`; an `http01` generator is rejected with `dnsMode: ns`, `gvcLink`, or `workloadLink`. A `dns01` generator with provider `cpln` (the default, `dns01: {}`) needs the `_acme-challenge` CNAME like built-in `dns01`; credentialed providers need none. | | `gvcLink` ⊻ `workloadLink` ⊻ `ports.routes` | Mutually exclusive. `workloadLink` (replica-direct) is Stateful only. | | `acceptAllHosts` ⊻ `acceptAllSubdomains` | Mutually exclusive; both require dedicated LB. | | `ports[].protocol` | `http`, `http2` (default), `tcp` (`tcp` requires dedicated LB). |