Mounting a custom trusted certificate authority bundle for external-secrets
You can configure the External Secrets Operator for Red Hat OpenShift to trust a custom certificate authority (CA) bundle when the external-secrets core controller communicates with external secret backends over transport layer socket (TLS). This is required when your organization uses a private CA or a self-signed certificate that is not included in the default system truststore.
To enable mounting a custom trusted CA, you reference a ConfigMap that contains the Privacy Enhanced Mail (PEM)-encoded CA certificates in the spec.controllerConfig.trustedCABundle field of the ExternalSecretsConfig custom resource (CR). The Operator mounts the bundle into the core controller pod and configures the TLS library to use it alongside the default system trust stores.
The External Secrets Operator for Red Hat OpenShift applies the following rules to the CA bundle ConfigMap:
-
The
ConfigMapmust reside in theexternal-secretsnamespace and must contain only PEM-encoded X.509 CA certificates. Leaf certificates and private key PEM blocks are rejected. -
If the
ConfigMapkey contains an invalid bundle, theExternalSecretsConfigCR enters aDegradedstate. The Operator automatically recovers and mounts the bundle when theConfigMapis corrected, without requiring manual intervention. -
If the referenced
ConfigMapdoes not exist, the Operator removes any previously mounted CA bundle from the core controller deployment and sets theExternalSecretsConfigCR to aDegradedstate until theConfigMapis created. -
The CA bundle is mounted only on the core
external-secretscontroller container. The webhook and cert-controller containers are not affected. -
If the
ConfigMaphas theconfig.openshift.io/inject-trusted-cabundle: "true"label and a cluster proxy is configured, the Operator skips the user-defined mount. The cluster-wide CA bundle injected by the Cluster Network Operator (CNO) is already available to the controller through the proxy CA bundle mechanism.
-
You have access to the cluster with
cluster-adminprivileges. -
You have installed the External Secrets Operator for Red Hat OpenShift and created the
ExternalSecretsConfigCR. -
A
ConfigMapcontaining PEM-encoded X.509 CA certificates exists in theexternal-secretsnamespace.
-
Create the
ConfigMapcontaining your CA bundle by running the following command:$ oc create configmap user-ca-bundle \ --from-file=ca-bundle.crt=/path/to/ca.pem \ -n external-secrets -
Edit the
ExternalSecretsConfigCR by running the following command:$ oc edit externalsecretsconfigs.operator.openshift.io cluster -
Add the
trustedCABundlefield underspec.controllerConfig:apiVersion: operator.openshift.io/v1alpha1 kind: ExternalSecretsConfig metadata: name: cluster spec: controllerConfig: trustedCABundle: name: user-ca-bundle key: ca-bundle.crtwhere:
spec.controllerConfig.trustedCABundle.name-
Specifies the name of the
ConfigMapin theexternal-secretsnamespace that contains the CA certificate bundle. spec.controllerConfig.trustedCABundle.key-
Optional. Specifies the key within the
ConfigMapthat holds the PEM-encoded CA bundle. The default isca-bundle.crt.
-
Verify that the CA bundle volume is mounted on the core controller deployment by running the following command:
$ oc get deployment external-secrets \ -n external-secrets \ -o jsonpath='{.spec.template.spec.volumes}' | jq '.[] | select(.name=="user-ca-bundle")'Example output{ "configMap": { "defaultMode": 420, "items": [ { "key": "ca-bundle.crt", "path": "ca-bundle.crt" } ], "name": "trusted-ca-bundle-for-es" }, "name": "user-ca-bundle" } -
Verify that the
SSL_CERT_DIRis set on the core controller container by running the following command:$ oc set env deployment/external-secrets \ -n external-secrets \ --list | grep SSL_CERT_DIRExample outputSSL_CERT_DIR=/etc/pki/tls/user-certs:/etc/pki/tls/certs:/etc/ssl/certs -
Verify that the
ExternalSecretsConfigCR is not in aDegradedstate by running the following command:$ oc get externalsecretsconfigs.operator.openshift.io cluster \ -o jsonpath='{.status.conditions[?(@.type=="Degraded")]}' | jq .Example output{ "lastTransitionTime": "2026-06-22T10:29:11Z", "message": "", "observedGeneration": 5, "reason": "Ready", "status": "False", "type": "Degraded" }The
Degradedcondition should show"status": "False". If the condition isTrue,review the message field for the specific validation error and correct the referencedConfigMap.