Skip to content

mTLS with Cloudflare Access

Setting up mTLS with Cloudflare Access can help in cases where the customer:

  • Already has existing Client Certificates on devices.
  • Needs to protect Access applications with Bring Your Own CA (BYOCA).
  • Needs to integrate with a Zero Trust solution.

1. Create a CA

The CA certificate can be from a publicly trusted CA or self-signed.

In case you want to create your own CA from scratch, you can follow these example steps and adapt the information to your own needs:

  1. Create a JSON file called ca-csr.json:
{
"CN": "Cloudflare Access Testing CA",
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"C": "US",
"L": "LA",
"O": "Access Testing",
"OU": "CA",
"ST": "California"
}
]
}
  1. Create a JSON file called ca-config.json:
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"server": {
"usages": ["signing", "key encipherment", "server auth"],
"expiry": "8760h"
},
"client": {
"usages": ["signing","key encipherment","client auth"],
"expiry": "8760h"
}
}
}
}
  1. Run the following cfssl command to generate the CA certificate ca.pem:
cfssl gencert -initca ca-csr.json | cfssljson -bare ca

2. Create Client Certificates

  1. In order to create the Client Certificates, you need to prepare the following JSON file called client-csr.json:
{
"CN": "mtls-access.example.com", # replace with your own hostname
"hosts": ["mtls-access.example.com"], # replace with your own hostname
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"C": "US",
"L": "Austin",
"O": "Access",
"OU": "Access Admins",
"ST": "Texas"
}
]
}
  1. Now you can run the following command to generate the Client Certificates, which will output the files client.pem, client-key.pem and client.csr:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client-csr.json | cfssljson -bare client

3. Add mTLS CA certificate to Cloudflare Access

Follow the steps outlined in the developer documentation.

Using the example from Step 2: upload the ca.pem to your Cloudflare Access account via the dashboard or Cloudflare API.

Do not forget to enter the fully-qualified domain names (FQDN / associated hostnames) that will use this CA certificate.

Customers can identify which client sends the Client Certificates by forwarding client certificate headers to the origin server. Customers can then store and use the certificate information such as Common Name (CN), Serial number, and other fields along with the device number to perform additional checks or logics.

Additionally, authenticated requests also send the Cf-Access-Jwt-Assertion\ JWT header to the origin server. To decode the header value, you can use jwt.io.

4. Create the self-hosted applications

Finally, the hostname you want to protect with mTLS needs to be added as a self-hosted app in Cloudflare Access, defining an Access Policy which uses the action Service Auth and the Selector “Valid Certificate”, or simply requiring an IdP authentication. You can also take advantage of extra requirements, such as the “Common Name” (CN), which expects the indicated hostname, and more Selectors. Alternatively, one can also extend ZTNA with external authorization and serverless computing.

Demo

With the Public and Private Client Certificates in the same directory, with this cURL command, we will gain access:

curl -IXGET --cert client.pem --key client-key.pem https://mtls-access.example.com/
HTTP/2 200
server: cloudflare

Without the certificates, we'd see the following:

curl -I https://mtls-access.example.com/mtls-test
HTTP/2 401
server: cloudflare