Configure mTLS for a Client

Use the Auth0 Management API to configure mTLS for a client:

Self-signed certificates

Use self-signed certificates to verify the client’s identity during mTLS authentication. However, self-signed certificates have the following limitations

  • Self-signed certificates are not accepted by some cloud providers such as Amazon.

  • To ensure the stability of our platform, Auth0 limits customers to two registered certificates.

Generate a certificate

To authenticate using self-signed mTLS, you must create a new self-signed client certificate. 

The following code sample generates a new self-signed certificate:

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=CommonNameOrHostname"

Was this helpful?

/

If using curl or Wget, the PEM certificate must be JSON escaped before you pass it to Auth0. For example, replace a newline is with \r\n:

-----BEGIN PRIVATE KEY-----\r\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDDXAVKQo2SUMHH\r\no9ecWYNiL5\/yva5NSj8uQjKoeRAsOIOAyOBTLxgwmno13xZ8VDkcT1cHTlC+2CkE\r\noBII4OUbHPVof+dtknkL+jUBdIPX1QvlGSUbzduZE4hEEQ8zH6w4EAA2VN72Bymn\r\nT8i\/+Tz9Dx6M1nkuXPCwM7sYEuq5OrqT5yVB6KByKKElp\/tauJkHp0st04iGDgl2\r\nFJUt3QJFCFewTDDdGq62otVJxHfouXPmHBQjzf+f1CZy+N0q2z+JGRt44YZq+F9y\r\ne3RWawvv2x3TXgRBLpvIKqf99LoPVdwozHl8QODu52dyelvLQ866XLhAALuMwic\/\r\nbQbolnMpAgMBAAECggEAf6LliekFmezNTmQLgIkzP7kh5XRsJu81bEGv20aNfHbH\r\n5CJZ\/b8tLMQgyIWiqURVs9taXtmaA7YyxmTWo5pb1WUMKWQ3je0+zMaCTxsS8Lau\r\n+NV+2zWaHd8XDnGe3qX43QAHQ3gb294+JqQH4vUyFZwFN7sAnXv3fQevW0Ewvics\r\nOua\/xNa7y5hbJUPZiQjRhO+n+gTEqpfsnPWNlm9hk\/wVnnjKvMfstN4zUbznRAoN\r\nW8TK82tiVWAXW4CjgIBtVRZjTA9x3UOtbhcvNzaTRxc+scCpIpAVuurS+ZIKZdpm\r\nNnhiOk3akpLU3KZrm8C5JQRn8cupY9WkfCiLXbMFAQKBgQD9JfVMv6zDeNvExneR\r\n7fZDIT2UAEhYExwRJwQPyxkVPwev9HBYuuaaknIbomWTkt\/B6Q3k3p6VI4lxhnVl\r\nbkpOYl5UquP3VoVROEJts224hKgVcLw6s+i+lZDOAleNgbN7rj82l4BIu+SEj\/7c\r\nz94hAa\/wRRvsW+QnxF1sZnpY+QKBgQDFj2h8I4noFJk3sbbk3qQdi5+49ibWSuhc\r\nXVpU+0dQ1lRlhXYT9cDMc22HRt8hjXUNRhdpXvOqVaFiBjv9wBsmFyaJO3tOK3uE\r\ndBgD4lF03bnbGI7\/I3DivW\/tyEMS5JXI\/qrpdWor+wR30c5M\/45y2AGpjwnoGf+D\r\nX8SAMzknsQKBgQCrSljuIrBK3+eNAWH821CL4d0h3QMWnW+bZ5QG\/70sNCcGd1bh\r\noy3Qn5EYg81JitNfCUw+dihF7\/LbX0jmZjdfTI5Zqfxw6xlweKnyQrvWY+S8BTlI\r\nW138P4Xo74rAlGeXI7NgRCkojgK1dB3W2cyK9vJOmOSpDRCXm\/Y\/GCRnOQKBgCE\/\r\n75\/lA1LSFK9w8401g32NgEZK92JdnRnehFOFLw2F5RJpEeRuGhLO4oJABVHKUwb2\r\n4v3TA0OJwe2Tiwk8CdWxU8UJA8m2O8WhHGGa94apwpwDWB3MwzUGGQ52BAPsAOGh\r\nKva70jCwwKHB5+zBniHqBO2aq1oq9fwQZCwHcvkhAoGBAIa8QMHNrX7AuCSAeR4\/\r\n\/7XrGU1a4oExz417AYgZOuGaYQAI5BMIjRZZ3JTzO\/QsmkzeS1tFuBlih8li\/t4l\r\nE2TdnKhy376A6QWfbTDkJN6gzFeaMKwe98mOHKeq0KZITGYVTSa2AYH5zaro0Yku\r\nonOH1NdyEKFFgxGLg7wveYUW\r\n-----END PRIVATE KEY-----

Was this helpful?

/

Create a new client

To create a new client, make a POST call to the /clients endpoint with the following payload:

  • $client_name: the name for the new client

  • $credential_name: the name for the public key 

  • $credential_certificate: the content of $certificate_pem generated in the previous step

curl --location --request POST 'https://$tenant/api/v2/clients' \
  --header 'Authorization: Bearer $management_access_token' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "$client_name",
  "app_type": "non_interactive",
  "client_authentication_methods": {
    "self_signed_tls_client_auth": {
      "credentials": [{ 
        "name": "$credential_name", 
        "credential_type": "x509_cert", 
        "pem": "$credential_certificate"
      }]
    }
  },
  "jwt_configuration": {
    "alg": "RS256"
  }
}'

Was this helpful?

/

For more information, see the Create a client API documentation.

Patch an existing client

You can update an existing client to accept mTLS client authentication by removing any value in the token_endpoint_auth_method field and creating values in the client_authentication_methods field.

Create the credential resource

Once you generate a certificate, create the credential resource:

curl --location --request POST 'https://$tenant/api/v2/clients/$client_id/credentials' \
  --header 'Authorization: Bearer $management_access_token' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "$credential_name", 
  "credential_type": "x509_cert", 
  "pem": "$credential_certificate"
}'

Was this helpful?

/

Auth0 returns a credential ID in the response that you will need to associate the credential with the client.

For more information, see the Create a client credential API documentation.

Associate the credential with the client and disable token_endpoint_auth_method

Uploaded credentials are not automatically enabled for client authentication. You need to update the client authentication to use the new self-signed client certificate.

The following PATCH request sets the token_endpoint_auth_method to null, thus disabling Client Secret authentication. It also updates client_authentication_methods with the credential ID:

curl --location --request PATCH 'https://$tenant/api/v2/clients/$client_id' \
  --header 'Authorization: Bearer $management_access_token' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "token_endpoint_auth_method": null, 
  "client_authentication_methods": {
    "self_signed_tls_client_auth": {
      "credentials": [{ "id": $credential.id }]
    }
  }
}'

Was this helpful?

/

Once this request has completed, a Client Secret will no longer be accepted and clients must authenticate using mTLS.

For more information, see the Update a client API documentation.

Certificate authority signed certificates

Unlike self-signed certificates that are generated by the client and have no trust chain, certificate authority (CA) signed certificates are considered more trustworthy since they are issued by a trusted third party. CA-signed certificates are the only type of certificate accepted by some cloud providers such as Amazon.

CA-signed certificates have embedded in their identity information the notion of a Distinguished Name (DN). While each individual certificate created by a given CA is unique, they can share a common DN. When using CA-signed certificates, Auth0 stores the DN and compares forwarded client certificates with registered DNs.

Generate a certificate

The method of generating a CA-signed client certificate is highly dependent on the Public Key Infrastructure and outside of the scope of this document. We recommend generating at least a 2048-bit RSA key pair.

Create a new client

To create a client, make a POST call to the /clients endpoint with the following payload:

  • $client_name: the name for the new client

  • $credential_name: the name for the public key 

  • $credential_certificate: the content of $certificate_pem generated by the CA

curl --location --request POST 'https://$tenant/api/v2/clients' \
  --header 'Authorization: Bearer $management_access_token' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "$client_name",
  "app_type": "non_interactive",
  "client_authentication_methods": {
    "tls_client_auth": {
      "credentials": [{ 
        "name": "$credential_name", 
        "credential_type": "cert_subject_dn", 
        "pem": "$credential_certificate"
      }]
    }
  },
  "jwt_configuration": {
    "alg": "RS256"
  }
}'

Was this helpful?

/

Instead of passing the full PEM file, you can also pass the subject DN. The subject DN must match the extracted Distinguished Name (DN) of the client certificates sent during the mTLS handshake.

The following POST request creates a new client with the subject DN:

curl --location --request POST 'https://$tenant/api/v2/clients' \
  --header 'Authorization: Bearer $management_access_token' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "$client_name",
  "app_type": "non_interactive",
  "client_authentication_methods": {
    "tls_client_auth": {
      "credentials": [{ 
        "name": "$credential_name", 
        "credential_type": "cert_subject_dn", 
        "subject_dn": "C=XX\nST=StateName\nL=CityName\nO=CompanyName\nOU=CompanySectionName\nCN=CommonNameOrHostname"
      }]
    }
  },
  "jwt_configuration": {
    "alg": "RS256"
  }
}'

Was this helpful?

/
For more information, see the Create a client API documentation.

Patch an existing client

If you don’t want to create a new client to use mTLS, you can update an existing client to accept mTLS client authentication. This involves removing any value in the token_endpoint_auth_method field and creating values in the client_authentication_methods field.

Create the credential resource

Once you have generated a key pair exclusively for mTLS, create the credential resource. Make the following POST request to the /clients endpoint:

curl --location --request POST 'https://$tenant/api/v2/clients/$client_id/credentials' \
  --header 'Authorization: Bearer $management_access_token' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "$credential_name", 
  "credential_type": "cert_subject_dn", 
  "pem": "$credential_certificate"
}'

Was this helpful?

/

Instead of passing the full PEM file, you can pass the subject DN. The subject DN must match the extracted Distinguished Name (DN) of the client certificates sent during the mTLS handshake.

The following code sample creates the credential resource using the Subject DN:

curl --location --request POST 'https://$tenant/api/v2/clients/$client_id/credentials' \
  --header 'Authorization: Bearer $management_access_token' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "$credential_name", 
  "credential_type": "cert_subject_dn", 
  "subject_dn": "C=XX\nST=StateName\nL=CityName\nO=CompanyName\nOU=CompanySectionName\nCN=CommonNameOrHostname"
}'

Was this helpful?

/

When using either method, remember that the credential ID that gets returned in the response is needed to associate the credential with the client.

For more information, see the Create a client credential API documentation.

Associate the credential with the client and disable token_endpoint_auth_method

Although we have created the credential, we have not yet associated the credential with the client.

To do so, update  client_authentication_methods by making the following PATCH request to the /clients endpoint. In the same request, set token_endpoint_auth_method to null:

​​

curl --location --request PATCH 'https://$tenant/api/v2/clients/$client_id' \
  --header 'Authorization: Bearer $management_access_token' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "token_endpoint_auth_method": null, 
  "client_authentication_methods": {
    "tls_client_auth": {
      "credentials": [{ "id": $credential.id }]
    }
  }
}'

Was this helpful?

/

Once this request has completed, the client can only be authenticated using mTLS.

For more information, see the Update a client API documentation.

Revert a client to use a Client Secret

To restore your client’s configuration to authenticate using a Client Secret, disable client_authentication_methods and re-enable token_endpoint_auth_method with your desired authentication method.

In the following PATCH request, set token_endpoint_auth_method to client_secret_post to re-enable Client Secret authentication:

curl --location --request PATCH 'https://$tenant/api/v2/clients/$client_id' \
  --header 'Authorization: Bearer $management_access_token' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "token_endpoint_auth_method": "client_secret_post", 
  "client_authentication_methods": null
}'

Was this helpful?

/

For more information, see the Update a client API documentation.

Enable Token Binding

You can enable mTLS Token Binding independently of mTLS client authentication. For example, Token Binding can be used with Private Key JWT client authentication (JWTCA). You can enable Token Binding when creating or updating a client.

Create a new client

curl --location --request POST 'https://$tenant/api/v2/clients' \
  --header 'Authorization: Bearer $management_access_token' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "name": "$client_name",
  "app_type": "non_interactive",
  "access_token": {
    "tls_client_certificate_binding": true
  }
}'

Was this helpful?

/

Patch an existing client

curl --location --request PATCH 'https://$tenant/api/v2/clients/$client_id' \
  --header 'Authorization: Bearer $management_access_token' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "access_token": {
    "tls_client_certificate_binding": true
  }
}'

Was this helpful?

/

Disable Token Binding

curl --location --request PATCH 'https://$tenant/api/v2/clients/$client_id' \
  --header 'Authorization: Bearer $management_access_token' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "access_token": {
    "tls_client_certificate_binding": false
  }
}'

Was this helpful?

/

For more information, see the Create a client and Update a client API documentation.

Learn more