Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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) |
Expand Down Expand Up @@ -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
Expand Down
54 changes: 48 additions & 6 deletions reference/certificategenerator.mdx
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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

Expand All @@ -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.<domain>`. 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.<domain>` | 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.

<Note>Your CA must follow the CNAME when it looks up the TXT record. Most public CAs do; confirm with yours.</Note>

**In your own DNS zone**

Set `provider` and the matching block:

| `provider` | Settings | Secret type | Required access |
| :--- | :--- | :--- | :--- |
Expand All @@ -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

Expand Down Expand Up @@ -134,7 +160,23 @@ A DNS-01 generator for a commercial CA, with credentials for Route53:
</Tab>
</Tabs>

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
Expand Down
20 changes: 10 additions & 10 deletions reference/domain.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ When a `gvcLink` is configured, each workload in the GVC is served at `<workload

Certificate handling depends on `certChallengeType`:

- `dns01`: Control Plane issues a **wildcard** certificate covering all subdomains. Also create the `_acme-challenge` CNAME record shown in `status.dnsConfig` to delegate the challenge to Control Plane. Not needed with a `dns01` [certificate generator](#certificate-generator).
- `dns01`: Control Plane issues a **wildcard** certificate covering all subdomains. Also create the `_acme-challenge` CNAME record shown in `status.dnsConfig` to delegate the challenge to Control Plane. With a [certificate generator](#certificate-generator), the record is needed only when the generator uses the `cpln` DNS-01 provider.
- `http01` (or unset): Control Plane does not issue a certificate for subdomain-based routing — configure a [custom server certificate](#custom-server-certificate) on every port that enables TLS.

**Constraints:**
Expand Down Expand Up @@ -372,7 +372,7 @@ spec:
- The generator defines the challenge type, so `certChallengeType` must not be set.
- It cannot be combined with `tls.serverCertificate.secretLink`.
- An `http01` generator cannot be used with `dnsMode: ns`, `gvcLink`, or `workloadLink`. Use a `dns01` generator for wildcard certificates.
- A `dns01` generator writes the challenge record into your own DNS zone, so no `_acme-challenge` CNAME record is needed.
- A `dns01` generator with the `cpln` provider (the default) uses the same `_acme-challenge` CNAME record as the built-in `dns01` challenge. A `dns01` generator that writes into your own DNS zone (`route53`, `cloudDns`, `azureDns`, `cloudflare`) needs no `_acme-challenge` record.

## Apex Domain Considerations

Expand Down Expand Up @@ -701,7 +701,7 @@ These endpoints route traffic directly to a specific workload replica.
### Configuration

To configure a domain for replica-direct routing, you need to set the `workloadLink` property on the domain to the link of the workload.
The domain must also use `dnsMode: cname` with the `dns01` certificate challenge type.
The domain must also use `dnsMode: cname` with the `dns01` certificate challenge type, or a `dns01` [certificate generator](#certificate-generator).
The domain must define at least one port, and each port must contain exactly one route.

**Validation Rules:**
Expand Down Expand Up @@ -742,7 +742,7 @@ When a domain is configured for replica-direct routing, the DNS names for each r

Replica direct domains require specific DNS records in order to work correctly.

1. One **CNAME** record to redirect the `dns01` certificate challenge to Control Plane
1. One **CNAME** record to redirect the `dns01` certificate challenge to Control Plane. Not needed when the domain uses a [certificate generator](#certificate-generator) that writes into your own DNS zone.
| Host | TTL | Type | Value |
| :-------------- | :-- | :---- | :----------------------- |
| \_acme-challenge | 300 | CNAME | \_acme-challenge.cpln.app |
Expand Down Expand Up @@ -796,7 +796,7 @@ The domain status field indicates the current state of the domain configuration

### DNS Configuration Records

The `dnsConfig` field contains the DNS records that must be configured for the domain to function properly.
The `dnsConfig` field contains the DNS records that must be configured for the domain to function properly. Hosts are relative to the apex domain.

**DNS Record Structure:**
- `type`: DNS record type (e.g., "CNAME", "NS", "TXT")
Expand All @@ -811,14 +811,14 @@ The `dnsConfig` field contains the DNS records that must be configured for the d
{
"type": "CNAME",
"ttl": 300,
"host": "sub.example.com",
"value": "cpln.app"
"host": "sub",
"value": "<gvcAlias>.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"
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion skill.md
Original file line number Diff line number Diff line change
Expand Up @@ -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). |
Expand Down
Loading