percona / percona/percona-postgresql-operator
An ACME `ClusterIssuer` cannot be used with `spec.tls.issuerConf`
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 385
- Forks
- 83
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 39
Description
Report
Setting spec.tls.issuerConf to an existing ACME ClusterIssuer (Let's Encrypt, or any ACME server) does not work. The Operator resolves this to external issuer mode and points all leaf Certificate resources at that issuer, but two of them request identifiers that ACME can never issue:
| Certificate | commonName and dnsNames |
|---|---|
<cluster>-replication-cert |
_crunchyrepl |
<cluster>-pgbackrest-client-cert |
pgbackrest@<cluster-uid> |
cert-manager submits commonName and every dnsNames entry to the ACME server as identifiers requiring an HTTP-01 or DNS-01 challenge. Neither of these strings is a resolvable DNS name, so the Order can never be fulfilled.
Both are client certificates whose identity is consumed by CN matching, not by hostname verification:
The other four certificates (cluster, instance, repo host, PgBouncer) are fine with an ACME issuer, given an ACME server that issues the clientAuth EKU and a spec.clusterServiceDNSSuffix set to a domain that server will validate.
More about the problem
There is also no usable workaround:
spec.secrets.customReplicationClientTLSSecretdoes bypass cert-manager for the replication cert (internal/controller/postgrescluster/patroni.go:381), but PostgreSQL validates that client cert againstssl_ca_file = /pgconf/tls/ca.crt(internal/postgres/parameters.go:31) - the CA of the cert-manager-issued server cert. A hand-supplied cert would have to be signed by the ACME CA, which is not possible.- The pgBackRest client cert has no equivalent field. The only opt-out is
spec.tls.certManagementPolicy: userProvidedOnly, which is all-or-nothing and disables cert-manager for the whole cluster.
Ideally the internal mTLS client certificates would be issued independently of spec.tls.issuerConf - either from the Operator's own CA or from a separately configurable issuer - since their identifiers are not DNS names and were never meant to be publicly validated.
Steps to reproduce
- Install cert-manager and create an ACME
ClusterIssuer. - Set
spec.tls.issuerConfto that issuer (kind: ClusterIssuer,group: cert-manager.io) and deploy a cluster.
Versions
not relevant
Anything else?
The in-flight cert-manager documentation for 3.1.0 (percona/k8spg-docs#414) lists ACME and Let's Encrypt as supported external issuers, and states that the configured issuer must sign every leaf certificate, including the replication and pgBackRest ones. That combination is not achievable, so the docs may need adjusting alongside the fix.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Trace how spec.tls.issuerConf selects issuers and how the six leaf Certificate resources are created. Review internal/controller/postgrescluster/patroni.go:381 and internal/postgres/parameters.go:31, then inspect the related certificate-generation entry points. Done means an ACME ClusterIssuer can be used without requesting non-DNS identifiers for the internal client certificates, while the documented certificate behavior is consistent.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, kubernetes, postgresql
- Domain
- backend, infrastructure, security
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100