Skip to content

feat: support loading the serving certificate from a pre-provisioned Secret - #2

Draft
psasidhar wants to merge 1 commit into
mainfrom
serving-cert-from-secret
Draft

feat: support loading the serving certificate from a pre-provisioned Secret#2
psasidhar wants to merge 1 commit into
mainfrom
serving-cert-from-secret

Conversation

@psasidhar

Copy link
Copy Markdown

Why

istio-csr generates its own serving CSR internally via pkiutil.GenCSR(), which produces a DNS-only CSR — no URI SAN. Issuers that derive the signing identity from a SPIFFE URI SAN cannot sign such a CSR. In our case, athenz-issuer parses spiffe://<trust-domain>/ns/<namespace>/sa/<service-account> to determine the Athenz domain/service to request from ZTS; with no URI SAN the serving-certificate request fails outright, and istio-csr cannot obtain its gRPC serving cert through the configured issuerRef.

What

Two new flags let istio-csr skip generating its serving CSR and instead load the serving certificate from a pre-provisioned Secret (e.g. maintained by a cert-manager Certificate resource, which gives full control of CSR contents including URI SANs):

--serving-certificate-secret-name       string
--serving-certificate-secret-namespace  string

Changes by file:

  • pkg/tls/tls.go — new loadFromSecret() path: reads tls.crt / tls.key / ca.crt from the named Secret and returns the tls.Certificate directly. fetchCertificate() takes this path when --serving-certificate-secret-name is set; the original GenCSR() path is unchanged otherwise. The Secret is re-read on the existing rotation schedule, so renewals performed by cert-manager are picked up automatically.
  • cmd/app/options/options.go — the two flags, plus a relaxation of the --serving-dns-names non-empty validation: in Secret mode the DNS SANs are embedded in the pre-provisioned certificate, so requiring the flag would force dead configuration.
  • cmd/app/app.go — passes the existing Kubernetes client into tls.NewProvider() so loadFromSecret() can call the Secrets API.

Default behavior is fully unchanged when the flags are not set.

Usage

# cert-manager Certificate producing the serving cert with the URI SAN the issuer needs
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: istio-csr-serving
  namespace: cert-manager
spec:
  secretName: cert-manager-istio-csr-athenz-tls
  commonName: example.k8s.cert-manager-istio-csr
  uris:
  - spiffe://athenz.io/ns/cert-manager/sa/example.k8s.cert-manager-istio-csr
  dnsNames:
  - cert-manager-istio-csr.cert-manager.svc
  - cert-manager-istio-csr.cert-manager.svc.cluster.local
  issuerRef:
    name: athenz-istio-issuer
    kind: AthenzClusterIssuer
    group: cert-manager.athenz.io
--serving-certificate-secret-name=cert-manager-istio-csr-athenz-tls
--serving-certificate-secret-namespace=cert-manager

Status

  • Draft, for team review of the approach.
  • Running in our Istio ambient test cluster: istiod connects to istio-csr's gRPC endpoint and verifies the Athenz-issued serving cert against the mesh trust bundle; workload/waypoint SVID issuance flows through it.
  • TODO before upstreaming to cert-manager/istio-csr: unit tests for loadFromSecret() and the option validation, docs for the new flags.

🤖 Generated with Claude Code

…Secret

istio-csr generates its own serving CSR via pkiutil.GenCSR(), which produces a DNS-only CSR with no URI SAN. Issuers that derive the signing identity from a SPIFFE URI SAN (e.g. an Athenz issuer, where the URI carries the domain and service to request from the CA) cannot sign such a CSR, so the serving certificate cannot be issued through the configured issuerRef at all.

This adds an alternative: two new flags, --serving-certificate-secret-name and --serving-certificate-secret-namespace, tell istio-csr to skip generating its serving CSR and instead load tls.crt / tls.key / ca.crt from a pre-provisioned Secret (e.g. maintained by a cert-manager Certificate resource, which allows full control of the CSR contents including URI SANs). The Secret is re-read on the rotation schedule so renewals by cert-manager are picked up. The --serving-dns-names requirement is relaxed in Secret mode, where DNS SANs are embedded in the pre-provisioned certificate. Default behavior is unchanged when the flags are not set.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Sasi Palaka <palakas@yahooinc.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant