{
  "schema_version": 2,
  "id": "operate/rs/security/certificates/certificate-based-authentication",
  "title": "Certificate-based authentication",
  "url": "https://redis.io/docs/latest/operate/rs/security/certificates/certificate-based-authentication/",
  "summary": "Certificate-based authentication allows secure, passwordless access to the REST API and databases.",
  "tags": [
    "docs",
    "operate",
    "rs"
  ],
  "last_updated": "2026-09-24T09:16:28+01:00",
  "page_type": "content",
  "content_hash": "dadc6a567374ff1a1ff3f2503460338dd2a42d833c15ede2d68eb4d9172685f5",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "You can set up certificate-based authentication for specific users to enable secure, passwordless access to the Redis Software [REST API](https://redis.io/docs/latest/operate/rs/references/rest-api) and databases."
    },
    {
      "id": "certificate-based-authentication-for-the-rest-api",
      "title": "Certificate-based authentication for the REST API",
      "role": "content",
      "text": ""
    },
    {
      "id": "set-up-certificate-based-authentication-for-the-rest-api",
      "title": "Set up certificate-based authentication for the REST API",
      "role": "content",
      "text": "To set up certificate-based authentication:\n\n1. Add a trusted CA certificate `mtls_trusted_ca` to the cluster using an [update cluster certificates](https://redis.io/docs/latest/operate/rs/references/rest-api/requests/cluster/certificates) request:\n\n    **Redis Software v7.22.2 and later:**\n\nFor Redis Software versions 7.22.2 and later, use:\n\n[code example]\n\n**Redis Software v7.22.0 and earlier:**\n\nFor Redis Software versions 7.22.0 and earlier, use:\n\n[code example]\n\n\n\n1. [Update cluster settings](https://redis.io/docs/latest/operate/rs/references/rest-api/requests/cluster#put-cluster) with mutual TLS (mTLS) configuration using one of the following options:\n\n    **Without subject validation:**\n\nAdditional certificate validation is optional. To enable mutual TLS without subject validation, use:\n\n[code example]\n\n**With SAN validation:**\n\nFor certificate validation by Subject Alternative Name (SAN), use:\n\n[code example]\n\nReplace the placeholder value `<>` with your client certificate's Subject Common Name or SAN DNS entry.\n\n**Example certificate and mTLS settings**\n\nIf a client certificate has:\n\n- Subject: `CN=client.example.com`\n\n- SAN: `DNS:app1.example.com, DNS:client.example.com, DNS:app1-prod.example.com`\n\nYou can use any of these values for the CN in `mtls_authorized_subjects`:\n\n[code example]\n\n**With Full Subject Name validation:**\n\nFor certificate validation by full Subject Name, use:\n\n[code example]\n\nReplace the placeholder values `<>` with your client certificate's subject values.\n\n**Example certificate and mTLS settings**\n\nIf a client certificate has:\n\n- Subject: `CN=client.example.com`\n\n- SAN: `DNS:app1.example.com, DNS:client.example.com, DNS:app1-prod.example.com`\n\nYou can use any of these values for the CN in `mtls_authorized_subjects`:\n\n[code example]\n\n\n\n1. When you [create new users](https://redis.io/docs/latest/operate/rs/references/rest-api/requests/users#post-user), include `\"auth_method\": \"certificate\"` and `certificate_subject_line` in the request body:\n\n    [code example]\n\n    Replace the placeholder values `<>` with your client certificate's subject values.\n\n    > [!NOTE]\n    > The `certificate_subject_line` must:\n    >\n    > - Follow [RFC 2253](https://www.rfc-editor.org/rfc/rfc2253) format.\n    >\n    > - List the attributes in reverse order, starting with the Common Name (`CN`).\n    >\n    > - Not contain spaces after the commas that separate attributes.\n    >\n    > - Exactly match the certificate's RFC 2253 subject.\n    >\n    > - Contain only one Organizational Unit (`OU`) value.\n    >"
    },
    {
      "id": "authenticate-rest-api-requests",
      "title": "Authenticate REST API requests",
      "role": "security",
      "text": "To use the REST API with certificate-based authentication, you must provide a client certificate, signed by the trusted CA `mtls_trusted_ca`, and a private key.\n\nThe following example uses [cURL](https://curl.se/) to send a [REST API request](https://redis.io/docs/latest/operate/rs/references/rest-api/requests):\n\n[code example]"
    },
    {
      "id": "certificate-based-authentication-for-cluster-management",
      "title": "Certificate-based authentication for cluster management",
      "role": "content",
      "text": "Two cluster-management flows support certificate credentials when Basic and Digest authentication are disabled or unavailable: joining a node to a cluster, and managing an Active-Active database. These flows don't use JWT or LDAP.\n\nCertificate authentication isn't automatic—you must configure each flow to use certificate credentials instead of a username and password. First complete [Set up certificate-based authentication for the REST API](#set-up-certificate-based-authentication-for-the-rest-api) so the cluster has a trusted CA (`mtls_trusted_ca`) and mutual TLS enabled (`mtls_certificate_authentication`)."
    },
    {
      "id": "certificate-credentials",
      "title": "Certificate credentials",
      "role": "content",
      "text": "Certificate credentials consist of three values:\n\n| Value | Required | Description |\n|---|---|---|\n| `client_cert` | Yes | The client certificate. |\n| `client_key` | Yes | The client certificate's private key. |\n| `trusted_ca` | No | The CA that validates the API certificate the peer cluster presents. If you omit it, the cluster uses the certificates in its `mtls_trusted_ca.pem` file. |\n\nMutual TLS applies in both directions. The client presents its certificate, which the cluster validates against its locally configured `mtls_trusted_ca`. The cluster presents its API certificate chain, which the client validates using the CA configured for that connection. Make sure the CA that signed your client certificates is present in `mtls_trusted_ca` on the cluster.\n\nFor any given cluster, use either a username and password or certificate credentials—never both. A request that includes both for the same cluster fails.\n\nThe same three values take different formats depending on the interface:\n\n| Interface | Format |\n|-----------|--------|\n| Bootstrap API `credentials` | PEM strings |\n| [`rladmin cluster join`](https://redis.io/docs/latest/operate/rs/references/cli-utilities/rladmin/cluster/join) | File paths |\n| Active-Active REST API `certificate_auth` | PEM strings |\n| [`crdb-cli`](https://redis.io/docs/latest/operate/rs/references/cli-utilities/crdb-cli) | PEM strings |"
    },
    {
      "id": "join-a-node-to-the-cluster",
      "title": "Join a node to the cluster",
      "role": "content",
      "text": "To join a node with certificate credentials, include `client_cert`, `client_key`, and `trusted_ca` in the `credentials` object of a [bootstrap](https://redis.io/docs/latest/operate/rs/references/rest-api/requests/bootstrap) request. These fields take PEM strings:\n\n[code example]\n\n[`rladmin cluster join`](https://redis.io/docs/latest/operate/rs/references/cli-utilities/rladmin/cluster/join) accepts the same three values as file paths, not PEM strings:\n\n[code example]"
    },
    {
      "id": "manage-an-active-active-database",
      "title": "Manage an Active-Active database",
      "role": "content",
      "text": "Each participating cluster in an Active-Active database authenticates separately. To use certificate credentials for a cluster, replace that cluster's `credentials` object with a `certificate_auth` object.\n\nParticipating clusters can use different authentication methods, so you can migrate them from passwords to certificates one at a time. In the following example, the first cluster still uses a username and password while the second uses certificate credentials:\n\n[code example]\n\nTo create an Active-Active database with certificate credentials from the command line, use [`crdb-cli crdb create`](https://redis.io/docs/latest/operate/rs/references/cli-utilities/crdb-cli/crdb/create). The `--instance` option takes PEM strings:\n\n[code example]\n\nTo add a participating cluster to an existing Active-Active database, use [`crdb-cli crdb add-instance`](https://redis.io/docs/latest/operate/rs/references/cli-utilities/crdb-cli/crdb/add-instance). Its `--instance` option accepts the same fields as `crdb-cli crdb create`:\n\n[code example]\n\nTo switch an existing participating cluster from a username and password to certificate credentials, use [`crdb-cli crdb update`](https://redis.io/docs/latest/operate/rs/references/cli-utilities/crdb-cli/crdb/update) with the instance's `id`:\n\n[code example]"
    },
    {
      "id": "certificate-based-authentication-for-databases",
      "title": "Certificate-based authentication for databases",
      "role": "content",
      "text": ""
    },
    {
      "id": "set-up-certificate-based-authentication-for-databases",
      "title": "Set up certificate-based authentication for databases",
      "role": "content",
      "text": "To set up certificate-based authentication for databases:\n\n1. Enable mutual TLS for the relevant databases. See [Enable TLS](https://redis.io/docs/latest/operate/rs/security/encryption/tls/enable-tls) for detailed instructions.\n\n1. When you [create new users](https://redis.io/docs/latest/operate/rs/references/rest-api/requests/users#post-user), include `\"auth_method\": \"certificate\"` and `certificate_subject_line` in the request body:\n\n    [code example]\n\n    Replace the placeholder values `<>` with your client certificate's subject values.\n\n    > [!NOTE]\n    > The `certificate_subject_line` must:\n    >\n    > - Follow [RFC 2253](https://www.rfc-editor.org/rfc/rfc2253) format.\n    >\n    > - List the attributes in reverse order, starting with the Common Name (`CN`).\n    >\n    > - Not contain spaces after the commas that separate attributes.\n    >\n    > - Exactly match the certificate's RFC 2253 subject.\n    >\n    > - Contain only one Organizational Unit (`OU`) value.\n    >"
    },
    {
      "id": "authenticate-database-connections",
      "title": "Authenticate database connections",
      "role": "security",
      "text": "To connect to a database with certificate-based authentication, you must provide a client certificate, signed by a trusted CA, and a private key. The client certificate must either be one you previously added to the database to [enable mutual TLS](https://redis.io/docs/latest/operate/rs/security/encryption/tls/enable-tls#enable-mutual-tls) (`authentication_ssl_client_certs` in the REST API), or be signed by one of these certificates.\n\nThe following example shows how to connect to a Redis database with [`redis-cli`](https://redis.io/docs/latest/operate/rs/references/cli-utilities/redis-cli):\n\n[code example]"
    },
    {
      "id": "limitations",
      "title": "Limitations",
      "role": "limits",
      "text": "- Certificate-based authentication is not implemented for the Cluster Manager UI."
    }
  ],
  "examples": [
    {
      "id": "set-up-certificate-based-authentication-for-the-rest-api-ex0",
      "language": "sh",
      "code": "PUT /v1/cluster/certificates\n{\n  \"certificates\": [\n    {\n      \"name\": \"mtls_trusted_ca\",\n      \"certificate\": \"<content of certificate PEM file>\"\n    }\n  ]\n}",
      "section_id": "set-up-certificate-based-authentication-for-the-rest-api"
    },
    {
      "id": "set-up-certificate-based-authentication-for-the-rest-api-ex1",
      "language": "sh",
      "code": "PUT /v1/cluster/update_cert\n{\n  \"name\": \"mtls_trusted_ca\",\n  \"certificate\": \"<content of certificate PEM file>\"\n}",
      "section_id": "set-up-certificate-based-authentication-for-the-rest-api"
    },
    {
      "id": "set-up-certificate-based-authentication-for-the-rest-api-ex2",
      "language": "sh",
      "code": "PUT /v1/cluster\n{\n  \"mtls_certificate_authentication\": true,\n  \"mtls_client_cert_subject_validation_type\": \"disabled\"\n}",
      "section_id": "set-up-certificate-based-authentication-for-the-rest-api"
    },
    {
      "id": "set-up-certificate-based-authentication-for-the-rest-api-ex3",
      "language": "sh",
      "code": "PUT /v1/cluster\n{\n  \"mtls_certificate_authentication\": true,\n  \"mtls_client_cert_subject_validation_type\": \"san_cn\",\n  \"mtls_authorized_subjects\": [{\n    \"CN\": \"<Subject Common Name or SAN DNS entry>\"\n  }]\n}",
      "section_id": "set-up-certificate-based-authentication-for-the-rest-api"
    },
    {
      "id": "set-up-certificate-based-authentication-for-the-rest-api-ex4",
      "language": "sh",
      "code": "PUT /v1/cluster\n{\n  \"mtls_certificate_authentication\": true,\n  \"mtls_client_cert_subject_validation_type\": \"san_cn\",\n  \"mtls_authorized_subjects\": [\n    {\"CN\": \"client.example.com\"},   // Subject CN\n    {\"CN\": \"app1.example.com\"},     // SAN DNS entry\n    {\"CN\": \"app1-prod.example.com\"} // Another SAN DNS entry\n  ]\n}",
      "section_id": "set-up-certificate-based-authentication-for-the-rest-api"
    },
    {
      "id": "set-up-certificate-based-authentication-for-the-rest-api-ex5",
      "language": "sh",
      "code": "PUT /v1/cluster\n{\n  \"mtls_certificate_authentication\": true,\n  \"mtls_client_cert_subject_validation_type\": \"full_subject\",\n  \"mtls_authorized_subjects\": [{\n    \"CN\": \"<Common Name>\",\n    \"OU\": [<array of Organizational Unit strings>],\n    \"O\": \"<Organization>\",\n    \"C\": \"<2-letter country code>\",\n    \"L\": \"<Locality (city)>\",\n    \"ST\": \"<State/Province>\"\n  }]\n}",
      "section_id": "set-up-certificate-based-authentication-for-the-rest-api"
    },
    {
      "id": "set-up-certificate-based-authentication-for-the-rest-api-ex6",
      "language": "sh",
      "code": "PUT /v1/cluster\n{\n  \"mtls_certificate_authentication\": true,\n  \"mtls_client_cert_subject_validation_type\": \"san_cn\",\n  \"mtls_authorized_subjects\": [\n    {\"CN\": \"client.example.com\"},   // Subject CN\n    {\"CN\": \"app1.example.com\"},     // SAN DNS entry\n    {\"CN\": \"app1-prod.example.com\"} // Another SAN DNS entry\n  ]\n}",
      "section_id": "set-up-certificate-based-authentication-for-the-rest-api"
    },
    {
      "id": "set-up-certificate-based-authentication-for-the-rest-api-ex7",
      "language": "sh",
      "code": "POST /v1/users\n    {\n      \"auth_method\": \"certificate\",\n      \"certificate_subject_line\": \"CN=<Common Name>,OU=<Organizational Unit>,O=<Organization>,L=<Locality>,ST=<State/Province>,C=<Country>\"\n    }",
      "section_id": "set-up-certificate-based-authentication-for-the-rest-api"
    },
    {
      "id": "authenticate-rest-api-requests-ex0",
      "language": "sh",
      "code": "curl --request <METHOD> --url https://<hostname-or-IP-address>:9443/<API-version>/<API-path> --cert client.pem --key client.key",
      "section_id": "authenticate-rest-api-requests"
    },
    {
      "id": "join-a-node-to-the-cluster-ex0",
      "language": "sh",
      "code": "POST /v1/bootstrap/join_cluster\n{\n  \"action\": \"join_cluster\",\n  \"cluster\": {\n    \"nodes\": \"<target-node-ip>\"\n  },\n  \"credentials\": {\n    \"client_cert\": \"-----BEGIN CERTIFICATE-----\\n...\\n-----END CERTIFICATE-----\\n\",\n    \"client_key\": \"-----BEGIN PRIVATE KEY-----\\n...\\n-----END PRIVATE KEY-----\\n\",\n    \"trusted_ca\": \"-----BEGIN CERTIFICATE-----\\n...\\n-----END CERTIFICATE-----\\n\"\n  }\n}",
      "section_id": "join-a-node-to-the-cluster"
    },
    {
      "id": "join-a-node-to-the-cluster-ex1",
      "language": "sh",
      "code": "rladmin cluster join nodes <target-node-ip> \\\n  client_cert <path-to-cert> \\\n  client_key <path-to-key> \\\n  trusted_ca <path-to-trusted-ca>",
      "section_id": "join-a-node-to-the-cluster"
    },
    {
      "id": "manage-an-active-active-database-ex0",
      "language": "sh",
      "code": "POST /v1/crdbs\n{\n  \"name\": \"cert-auth-aa\",\n  \"guid\": \"<guid>\",\n  \"default_db_config\": {\n    \"memory_size\": 104857600,\n    \"replication\": true\n  },\n  \"instances\": [\n    {\n      \"cluster\": {\n        \"name\": \"cluster1.local\",\n        \"url\": \"https://<cluster1-ip>:9443\",\n        \"credentials\": {\n          \"username\": \"<username>\",\n          \"password\": \"<password>\"\n        }\n      }\n    },\n    {\n      \"cluster\": {\n        \"name\": \"cluster2.local\",\n        \"url\": \"https://<cluster2-ip>:9443\",\n        \"certificate_auth\": {\n          \"client_cert\": \"-----BEGIN CERTIFICATE-----\\n...\\n-----END CERTIFICATE-----\\n\",\n          \"client_key\": \"-----BEGIN PRIVATE KEY-----\\n...\\n-----END PRIVATE KEY-----\\n\",\n          \"trusted_ca\": \"-----BEGIN CERTIFICATE-----\\n...\\n-----END CERTIFICATE-----\\n\"\n        }\n      }\n    }\n  ]\n}",
      "section_id": "manage-an-active-active-database"
    },
    {
      "id": "manage-an-active-active-database-ex1",
      "language": "sh",
      "code": "crdb-cli crdb create \\\n  --name cert-crdb \\\n  --instance \"fqdn=cluster1.local,username=<username>,password=<password>\" \\\n  --instance \"fqdn=cluster2.local,client_cert=<client-cert>,client_key=<client-key>,trusted_ca=<trusted-ca>\"",
      "section_id": "manage-an-active-active-database"
    },
    {
      "id": "manage-an-active-active-database-ex2",
      "language": "sh",
      "code": "crdb-cli crdb add-instance \\\n  --crdb-guid <crdb-guid> \\\n  --instance \"fqdn=cluster3.local,client_cert=<client-cert>,client_key=<client-key>,trusted_ca=<trusted-ca>\"",
      "section_id": "manage-an-active-active-database"
    },
    {
      "id": "manage-an-active-active-database-ex3",
      "language": "sh",
      "code": "crdb-cli crdb update \\\n  --crdb-guid <crdb-guid> \\\n  --credentials \"id=2,client_cert=<client-cert>,client_key=<client-key>,trusted_ca=<trusted-ca>\"",
      "section_id": "manage-an-active-active-database"
    },
    {
      "id": "set-up-certificate-based-authentication-for-databases-ex0",
      "language": "sh",
      "code": "POST /v1/users\n    {\n      \"auth_method\": \"certificate\",\n      \"certificate_subject_line\": \"CN=<Common Name>,OU=<Organizational Unit>,O=<Organization>,L=<Locality>,ST=<State/Province>,C=<Country>\"\n    }",
      "section_id": "set-up-certificate-based-authentication-for-databases"
    },
    {
      "id": "authenticate-database-connections-ex0",
      "language": "sh",
      "code": "redis-cli -h <hostname-or-IP-address> -p <port> --tls --cacert <redis_cert>.pem --cert redis_user.crt --key redis_user_private.key",
      "section_id": "authenticate-database-connections"
    }
  ]
}
