{
  "schema_version": 2,
  "id": "operate/kubernetes/security/certificates/cert-manager",
  "title": "Integrate cert-manager with Redis for Kubernetes",
  "url": "https://redis.io/docs/latest/operate/kubernetes/security/certificates/cert-manager/",
  "summary": "Automate TLS certificate management for Redis for Kubernetes using cert-manager.",
  "aliases": [
    "/operate/kubernetes/security/cert-manager/"
  ],
  "tags": [
    "docs",
    "operate",
    "kubernetes"
  ],
  "last_updated": "2026-09-28T15:03:12+01:00",
  "page_type": "content",
  "content_hash": "9921299ef0a8713e1317af56e29ef49b3d3309efe0f1139430e9cea7016d4bd1",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "[cert-manager](https://cert-manager.io/) is a Kubernetes add-on that automates the management and issuance of TLS certificates. The Redis operator integrates with cert-manager, so you can use automatically managed certificates for:\n\n- Redis Enterprise cluster (REC) components (API, CM, proxy, syncer, and others)\n- Database replication with TLS\n- LDAP client authentication\n- SSO/SAML certificates\n\nBenefits of using cert-manager include:\n\n- **Automatic certificate renewal**: cert-manager handles certificate rotation before expiration.\n- **Standardized management**: Use the same certificate management approach across your Kubernetes infrastructure.\n- **Multiple certificate authorities**: Support for Let's Encrypt, private CAs, Vault, and more.\n- **Automatic propagation**: For Active-Active databases, certificate changes automatically sync across all participating clusters.\n\n> [!WARNING]\n> The cert-manager integration uses Kubernetes secrets. It is not compatible with Vault-based secret management (when `clusterCredentialSecretType: vault`). See [HashiCorp Vault integration](https://redis.io/docs/latest/operate/kubernetes/security/vault) for details."
    },
    {
      "id": "prerequisites",
      "title": "Prerequisites",
      "role": "content",
      "text": "- Kubernetes cluster with Redis Software for Kubernetes 8.0.18 or later\n- cert-manager v1.19.0 or later installed\n\nIf cert-manager is not already installed, see the [cert-manager installation documentation](https://cert-manager.io/docs/installation/)."
    },
    {
      "id": "how-it-works",
      "title": "How it works",
      "role": "content",
      "text": "cert-manager creates standard Kubernetes TLS secrets with the following fields:\n\n- `tls.crt`: The certificate in PEM format\n- `tls.key`: The private key in PEM format\n- `ca.crt`: The root CA certificate\n\nThe Redis Enterprise operator automatically recognizes these secrets and can use them interchangeably with manually created secrets.\n\n> [!NOTE]\n> If you currently use opaque secrets for your certificates, you can switch to cert-manager's TLS secrets without any additional configuration changes to your Redis resources."
    },
    {
      "id": "supported-secret-formats",
      "title": "Supported secret formats",
      "role": "compatibility",
      "text": "The operator supports multiple field names for backward compatibility:\n\n| Purpose | Accepted field names |\n|---------|---------------------|\n| Certificate | `tls.crt`, `cert`, `certificate` |\n| Private key | `tls.key`, `key` |\n| CA certificate | `ca.crt` |\n\n> [!NOTE]\n> Support for the `tls.crt` and `tls.key` field names requires Redis Software for Kubernetes 8.0.18 or later. For secret requirements on earlier versions, see [Manage REC certificates](https://redis.io/docs/latest/operate/kubernetes/security/certificates/manage-rec-certificates).\n\n> [!NOTE]\n> The `ca.crt` field is automatically appended to the certificate chain when present. cert-manager typically populates this field when it has access to the root certificate."
    },
    {
      "id": "quick-start",
      "title": "Quick start",
      "role": "content",
      "text": "After you install cert-manager and configure an [`Issuer` or `ClusterIssuer`](https://cert-manager.io/docs/concepts/issuer/), create a `Certificate` resource to generate TLS secrets, then reference the secret name in your Redis custom resources."
    },
    {
      "id": "create-a-certificate-and-configure-your-rec",
      "title": "Create a certificate and configure your REC",
      "role": "content",
      "text": "The following example creates a certificate and references the generated secret in a `RedisEnterpriseCluster` resource:\n\n[code example]\n\nThe operator automatically reads the certificate from the `redis-api-tls` secret created by cert-manager. No additional configuration is needed, even if you are migrating from manually created opaque secrets."
    },
    {
      "id": "secure-all-cluster-components",
      "title": "Secure all cluster components",
      "role": "content",
      "text": "Request certificates for each component and reference them in the REC:\n\n[code example]\n\nEach secret name corresponds to a `Certificate` resource managed by cert-manager. For details on these fields, see the [RedisEnterpriseCluster API reference](https://redis.io/docs/latest/operate/kubernetes/reference/api/redis_enterprise_cluster_api)."
    },
    {
      "id": "database-replication-with-tls",
      "title": "Database replication with TLS",
      "role": "content",
      "text": "For database replication with client certificates:\n\n[code example]"
    },
    {
      "id": "ldap-client-authentication",
      "title": "LDAP client authentication",
      "role": "content",
      "text": "When using LDAP with client certificate authentication:\n\n[code example]\n\nFor more details on LDAP configuration, see [Enable LDAP authentication](https://redis.io/docs/latest/operate/kubernetes/security/authentication/ldap)."
    },
    {
      "id": "active-active-databases-with-automatic-certificate-sync",
      "title": "Active-Active databases with automatic certificate sync",
      "role": "content",
      "text": "For Active-Active databases, certificate updates to proxy or syncer certificates automatically trigger synchronization across all participating clusters:\n\n[code example]\n\nWhen cert-manager renews these certificates, the operator:\n\n1. Detects the secret change.\n1. Updates the certificate generation counter.\n1. Triggers a CRDB force update automatically.\n1. Synchronizes the new certificates to all participating clusters.\n\nNo manual intervention is required."
    },
    {
      "id": "use-production-certificate-authorities",
      "title": "Use production certificate authorities",
      "role": "content",
      "text": ""
    },
    {
      "id": "lets-encrypt-and-acme-issuers",
      "title": "Let's Encrypt and ACME issuers",
      "role": "content",
      "text": "You can use Let's Encrypt and other ACME issuers, but not as an out-of-the-box integration. ACME issuers don't populate the `ca.crt` field of the generated TLS secret with the root certificate, so the secret that cert-manager creates doesn't include the full certificate chain.\n\nRedis Software needs the full chain, including the root CA, to trust the certificate. Whenever cert-manager doesn't populate `ca.crt` with the root certificate, supply the full chain yourself:\n\n1. Assemble the full certificate chain, including the root CA certificate.\n1. Create a Kubernetes secret that contains the full chain.\n1. Reference that secret in your Redis custom resource instead of the secret that cert-manager generates.\n\n> [!NOTE]\n> This applies to any issuer that doesn't populate `ca.crt` with the root certificate, not only Let's Encrypt.\n\nFor production environments where the issuer supplies the full chain automatically, such as a private CA or HashiCorp Vault, no extra steps are required."
    },
    {
      "id": "private-ca",
      "title": "Private CA",
      "role": "content",
      "text": "For internal deployments with a private certificate authority:\n\n[code example]\n\nThe `ca-key-pair` secret must contain your CA's certificate and private key."
    },
    {
      "id": "migrate-from-manual-certificate-management",
      "title": "Migrate from manual certificate management",
      "role": "content",
      "text": "If you currently use manually created secrets, you can migrate to cert-manager without downtime.\n\n1. Install cert-manager and create issuers (as shown in previous examples).\n\n1. Create `Certificate` resources with **different secret names** than your current secrets:\n\n    [code example]\n\n1. Update your REC to reference the new secrets:\n\n    [code example]\n\n    The operator updates the cluster with the new certificates. For Active-Active databases, the changes automatically sync to all clusters.\n\n1. After verifying the new certificates work correctly, delete the old manually created secrets:\n\n    [code example]"
    },
    {
      "id": "certificate-renewal-and-monitoring",
      "title": "Certificate renewal and monitoring",
      "role": "content",
      "text": ""
    },
    {
      "id": "automatic-renewal",
      "title": "Automatic renewal",
      "role": "content",
      "text": "cert-manager automatically renews certificates before they expire based on the `renewBefore` setting in the `Certificate` spec:\n\n[code example]"
    },
    {
      "id": "monitor-certificate-status",
      "title": "Monitor certificate status",
      "role": "content",
      "text": "Check certificate status:\n\n[code example]\n\nView detailed certificate information:\n\n[code example]"
    },
    {
      "id": "troubleshooting",
      "title": "Troubleshooting",
      "role": "errors",
      "text": ""
    },
    {
      "id": "certificate-not-issued",
      "title": "Certificate not issued",
      "role": "content",
      "text": "Check the certificate status and cert-manager logs:\n\n[code example]\n\nCommon issues:\n\n- **Issuer not ready**: Verify your `Issuer` or `ClusterIssuer` is configured correctly.\n- **DNS validation failure**: For ACME issuers, ensure DNS records are correctly configured.\n- **Rate limits**: Let's Encrypt has rate limits. Use the staging environment for testing."
    },
    {
      "id": "operator-not-detecting-certificate-changes",
      "title": "Operator not detecting certificate changes",
      "role": "content",
      "text": "Verify the secret exists and has the correct format:\n\n[code example]\n\nConfirm the secret contains `tls.crt` and `tls.key` fields. Check operator logs:\n\n[code example]"
    },
    {
      "id": "certificate-chain-issues",
      "title": "Certificate chain issues",
      "role": "content",
      "text": "If you encounter certificate chain validation errors:\n\n1. Verify the `ca.crt` field is present in the secret (cert-manager populates this automatically when it has access to the root CA).\n1. If `ca.crt` is not present, ensure the certificate in `tls.crt` includes the full chain inline.\n1. Confirm the certificate chain is in the correct order: leaf certificate first, then intermediates, then root."
    },
    {
      "id": "best-practices",
      "title": "Best practices",
      "role": "content",
      "text": "- **Use appropriate certificate lifetimes**: 90 days with a 15-day renewal window for production. Use shorter lifetimes in development to test renewal.\n- **Configure proper DNS names**: Include all necessary DNS names and SANs in your `Certificate` spec.\n- **Monitor certificate expiration**: Set up alerts for certificate expiration, even with automatic renewal.\n- **Use `ClusterIssuers` for shared issuers**: If multiple namespaces need certificates from the same CA, use `ClusterIssuers` instead of namespace-scoped `Issuers`.\n- **Back up CA private keys**: If using a private CA, ensure the CA private key secret is backed up."
    },
    {
      "id": "see-also",
      "title": "See also",
      "role": "related",
      "text": "- [cert-manager documentation](https://cert-manager.io/docs/)\n- [Manage REC certificates](https://redis.io/docs/latest/operate/kubernetes/security/certificates/manage-rec-certificates)\n- [RedisEnterpriseCluster API reference](https://redis.io/docs/latest/operate/kubernetes/reference/api/redis_enterprise_cluster_api)\n- [RedisEnterpriseDatabase API reference](https://redis.io/docs/latest/operate/kubernetes/reference/api/redis_enterprise_database_api)\n- [HashiCorp Vault integration](https://redis.io/docs/latest/operate/kubernetes/security/vault)"
    }
  ],
  "examples": [
    {
      "id": "create-a-certificate-and-configure-your-rec-ex0",
      "language": "yaml",
      "code": "apiVersion: cert-manager.io/v1\nkind: Certificate\nmetadata:\n  name: redis-api-cert\n  namespace: redis-namespace\nspec:\n  secretName: redis-api-tls\n  duration: 2160h # 90 days\n  renewBefore: 360h # 15 days before expiration\n  issuerRef:\n    name: my-issuer\n    kind: ClusterIssuer\n---\napiVersion: app.redislabs.com/v1\nkind: RedisEnterpriseCluster\nmetadata:\n  name: rec\n  namespace: redis-namespace\nspec:\n  nodes: 3\n  certificates:\n    apiCertificateSecretName: redis-api-tls",
      "section_id": "create-a-certificate-and-configure-your-rec"
    },
    {
      "id": "secure-all-cluster-components-ex0",
      "language": "yaml",
      "code": "apiVersion: app.redislabs.com/v1\nkind: RedisEnterpriseCluster\nmetadata:\n  name: rec\nspec:\n  nodes: 3\n  certificates:\n    apiCertificateSecretName: api-tls\n    cmCertificateSecretName: cm-tls\n    proxyCertificateSecretName: proxy-tls\n    syncerCertificateSecretName: syncer-tls\n    metricsExporterCertificateSecretName: metrics-tls",
      "section_id": "secure-all-cluster-components"
    },
    {
      "id": "database-replication-with-tls-ex0",
      "language": "yaml",
      "code": "apiVersion: cert-manager.io/v1\nkind: Certificate\nmetadata:\n  name: replication-client-cert\n  namespace: redis-namespace\nspec:\n  secretName: replication-client-tls\n  issuerRef:\n    name: my-ca-issuer\n    kind: ClusterIssuer\n  commonName: replication-client\n---\napiVersion: app.redislabs.com/v1alpha1\nkind: RedisEnterpriseDatabase\nmetadata:\n  name: target-db\nspec:\n  replicaSources:\n    - replicaSourceType: SECRET\n      replicaSourceName: source-uri-secret\n      clientKeySecret: replication-client-tls",
      "section_id": "database-replication-with-tls"
    },
    {
      "id": "ldap-client-authentication-ex0",
      "language": "yaml",
      "code": "apiVersion: cert-manager.io/v1\nkind: Certificate\nmetadata:\n  name: ldap-client-cert\n  namespace: redis-namespace\nspec:\n  secretName: ldap-client-tls\n  issuerRef:\n    name: ldap-ca-issuer\n    kind: ClusterIssuer\n  commonName: redis-ldap-client\n---\napiVersion: app.redislabs.com/v1\nkind: RedisEnterpriseCluster\nmetadata:\n  name: rec\nspec:\n  nodes: 3\n  certificates:\n    ldapClientCertificateSecretName: ldap-client-tls\n  ldap:\n    protocol: LDAPS\n    servers:\n      - host: ldap.example.com\n        port: 636",
      "section_id": "ldap-client-authentication"
    },
    {
      "id": "active-active-databases-with-automatic-certificate-sync-ex0",
      "language": "yaml",
      "code": "apiVersion: app.redislabs.com/v1\nkind: RedisEnterpriseCluster\nmetadata:\n  name: rec\nspec:\n  nodes: 3\n  certificates:\n    proxyCertificateSecretName: proxy-tls\n    syncerCertificateSecretName: syncer-tls",
      "section_id": "active-active-databases-with-automatic-certificate-sync"
    },
    {
      "id": "private-ca-ex0",
      "language": "yaml",
      "code": "apiVersion: cert-manager.io/v1\nkind: ClusterIssuer\nmetadata:\n  name: private-ca-issuer\nspec:\n  ca:\n    secretName: ca-key-pair",
      "section_id": "private-ca"
    },
    {
      "id": "migrate-from-manual-certificate-management-ex0",
      "language": "yaml",
      "code": "apiVersion: cert-manager.io/v1\n    kind: Certificate\n    metadata:\n      name: new-api-cert\n    spec:\n      secretName: api-tls-new\n      issuerRef:\n        name: my-issuer\n        kind: ClusterIssuer",
      "section_id": "migrate-from-manual-certificate-management"
    },
    {
      "id": "migrate-from-manual-certificate-management-ex1",
      "language": "yaml",
      "code": "apiVersion: app.redislabs.com/v1\n    kind: RedisEnterpriseCluster\n    metadata:\n      name: rec\n    spec:\n      certificates:\n        apiCertificateSecretName: api-tls-new",
      "section_id": "migrate-from-manual-certificate-management"
    },
    {
      "id": "migrate-from-manual-certificate-management-ex2",
      "language": "bash",
      "code": "kubectl delete secret old-api-tls -n redis-namespace",
      "section_id": "migrate-from-manual-certificate-management"
    },
    {
      "id": "automatic-renewal-ex0",
      "language": "yaml",
      "code": "spec:\n  duration: 2160h    # 90 days\n  renewBefore: 360h  # Renew 15 days before expiration",
      "section_id": "automatic-renewal"
    },
    {
      "id": "monitor-certificate-status-ex0",
      "language": "bash",
      "code": "kubectl get certificate -n redis-namespace",
      "section_id": "monitor-certificate-status"
    },
    {
      "id": "monitor-certificate-status-ex1",
      "language": "bash",
      "code": "kubectl describe certificate redis-api-cert -n redis-namespace",
      "section_id": "monitor-certificate-status"
    },
    {
      "id": "certificate-not-issued-ex0",
      "language": "bash",
      "code": "kubectl describe certificate <certificate-name> -n <namespace>\nkubectl logs -n cert-manager deployment/cert-manager",
      "section_id": "certificate-not-issued"
    },
    {
      "id": "operator-not-detecting-certificate-changes-ex0",
      "language": "bash",
      "code": "kubectl get secret <secret-name> -n <namespace> -o yaml",
      "section_id": "operator-not-detecting-certificate-changes"
    },
    {
      "id": "operator-not-detecting-certificate-changes-ex1",
      "language": "bash",
      "code": "kubectl logs -n <operator-namespace> deployment/redis-enterprise-operator",
      "section_id": "operator-not-detecting-certificate-changes"
    }
  ]
}
