Use custom TLS certificates
When you deploy MinIO Key Management Service (MinKMS) on Kubernetes with the MinKMS Operator, the Operator generates the MinKMS TLS certificate automatically using the Kubernetes Certificate Signing Request (CSR) API: it submits a CSR with the kubernetes.io/kubelet-serving signer, which the Kubernetes API server signs using the cluster’s kubelet CA. (On OpenShift the Operator instead uses the cluster’s service CA; on Amazon EKS it uses the beta.eks.amazonaws.com/app-serving signer.)
If you already have certificates from your own Certificate Authority (CA) or public key infrastructure (PKI), you can provide them to MinKMS instead, rather than relying on the Operator-provisioned certificates or on cert-manager.
You provide a custom certificate by storing it in a Kubernetes secret and referencing that secret from the MinKMS resource.
Certificate requirements
The custom certificate must meet the MinKMS certificate requirements and be valid for the following DNS names:
<name>-minkms.<namespace><name>-minkms.<namespace>.svc<name>-minkms.<namespace>.svc.<cluster domain>*.<name>-minkms-hl.<namespace>.svc.<cluster domain>
The first three cover client and API access. The wildcard headless SAN is required because the Operator connects to individual MinKMS pods.
where:
-
<name>is the name of the MinKMS deployment, defined in themetadata.namefield of theMinKMSresource. -
<namespace>is the namespace where MinKMS is installed, defined in themetadata.namespacefield of theMinKMSresource. -
<cluster domain>is the internal root DNS domain assigned in your Kubernetes cluster. Typically this iscluster.local, but confirm the value by checking your CoreDNS configuration. Different Kubernetes providers manage the root domain differently.
Provide the certificate to MinKMS
-
Create a secret in the MinKMS namespace containing the server certificate and its private key. MinKMS resolves the entry names from the secret type:
kubernetes.io/tls: certificate undertls.crt, key undertls.keyOpaque(or any other type): certificate underpublic.crt, key underprivate.key
For example, as a
kubernetes.io/tlssecret:kubectl create secret tls <minkms-server-tls> \ --cert=path/to/server.crt \ --key=path/to/server.key \ --namespace <namespace>Tip<minkms-server-tls>can be any name; reference the same name in the MinKMSexternalCertSecretfield below. -
Deploy MinKMS so that it:
-
Does not generate its own certificates (
disableAutoCert: true), and -
References the secret (
externalCertSecret).
The following
minkmschart values provide a baseline configuration meeting these requirements:# minkms values.yaml minkms: certificates: disableAutoCert: true externalCertSecret: - name: <minkms-server-tls> -
The Operator mounts the secret into every MinKMS pod (as a projected volume that references the secret directly), so updates to the secret propagate to the pods automatically.
Renew custom certificates
To renew a custom certificate, update the certificate and key entries in the secret with the new certificate and key (tls.crt/tls.key for a kubernetes.io/tls secret, public.crt/private.key for an Opaque secret).
MinKMS reloads the updated certificate automatically.
See Certificate Management for reload behavior and timing.
Trust the issuing CA from clients
Any client that connects to MinKMS over TLS must trust the CA that signed the custom certificate. Distribute the CA certificate to the trust store of each client.
For AIStor Object Store using MinKMS for Server-Side Encryption, the CA that signed the MinKMS server certificate must be added to the Object Store’s trusted CAs (objectStore.certificates.trustedCAs); otherwise the Object Store cannot verify the MinKMS endpoint and SSE-KMS operations fail with TLS errors.
-
Create a secret containing the CA certificate in the Object Store namespace. As with
externalCertSecret, the Object Store resolves the key from the secret type:kubernetes.io/tls: CA undertls.crtOpaque(or any other type): CA underpublic.crt
For example, as an
Opaquesecret:kubectl create secret generic <minkms-ca> \ --from-file=public.crt=path/to/ca.crt \ --namespace <object-store-namespace> -
Reference that secret under
objectStore.certificates.trustedCAsin the Object Store Helm chart values:# object-store values.yaml objectStore: certificates: trustedCAs: - name: <minkms-ca>
See the AIStor Object Store network encryption documentation and Server-Side Encryption with AIStor Key Manager for the full encryption configuration.
Known issues
The minkms Helm chart does not expose externalCertSecret on older versions
The minkms Helm chart version 2.3.0 (and earlier) does not render externalCertSecret into the MinKMS resource, so setting it under minkms.certificates in values.yaml has no effect. Newer charts include this field.
Workaround: add the externalCertSecret block to the chart’s templates/minkms.yaml, under the certificates: section, right after disableAutoCert:
disableAutoCert: {{ .disableAutoCert }}
{{- with .externalCertSecret }}
externalCertSecret: {{- toYaml . | nindent 6 }}
{{- end }}
With that block in place, set the secret through values.yaml as usual:
# minkms values.yaml
minkms:
certificates:
disableAutoCert: true
externalCertSecret:
- name: <name>-minkms-tls
The Operator does not load externalCertSecret for cluster management on older releases
To manage a MinKMS cluster (for example, to scale it up or down), the Operator connects to the MinKMS service and must trust the server certificate it presents. Recent Operators load the certificate referenced by externalCertSecret into that client’s trust store automatically.
The released Operator RELEASE.2026-04-13T10-27-16Z.operator and earlier do not (on OpenShift, this is the OLM-installed minio-minkms-operator.v2026.4.13102716 CSV and earlier). These releases only trust the certificate found in the secret named <name>-minkms-tls (where <name> is the MinKMS metadata.name). With a custom certificate stored under any other name, the client cannot verify the endpoint and cluster management operations fail with TLS errors.
Workaround: name the secret holding the custom server certificate exactly <name>-minkms-tls, and reference that same name in externalCertSecret:
kubectl create secret tls <name>-minkms-tls \
--cert=path/to/server.crt \
--key=path/to/server.key \
--namespace <namespace>
The MinKMS pods serve the certificate from externalCertSecret, while the Operator reads the same secret by its <name>-minkms-tls name to build the client it uses for cluster management. Because disableAutoCert: true stops the Operator from generating its own certificate, it will not overwrite this secret.