# Configure & Associate an mTLS Certificate

import Tag from '~/components/webkit/Tag.vue'
import Tabs from '~/components/tabs/Tabs'
import Code from '~/components/Code/Code.astro'

import Apiv4Rollout from '~/includes/snippets/apiv4Rollout/en/snippet.mdx'

<Apiv4Rollout />

[Mutual Transport Layer Security (mTLS)](/en/documentation/products/secure/firewall/mtls/) is a security protocol that enables two-way authentication and encryption for network interaction. It confirms that both the client and the server are authenticated and have the clearance for effective communication.

To configure mTLS in your applications, you need a [digital certificate](/en/documentation/products/guides/secure/digital-certificates/) with mTLS support signed by a third-party certificate authority (CA). At Azion, this type of certificate is called a **Trusted CA**.

There are separate instructions for API v3 using [legacy Domains](/en/documentation/products/build/applications/domains/) settings and API v4 using the new [Workloads](/en/documentation/products/secure/workloads) product.

:::tip
In this guide, there are separate instructions for API v3 and API v4. If you're not sure which steps apply to your account, see [the Verify Your Account Migration guide](/en/documentation/products/guides/verify-account-migration/) to determine if your account has already been migrated.
:::


---

## Adding a Trusted CA certificate and associating it to a domain

<Tabs client:visible>
    <Fragment slot="tab.consoleworkloads">Console - Workloads</Fragment>
    <Fragment slot="tab.consoledomains">Console - Domains</Fragment>
    <Fragment slot="tab.apiv3">API v3</Fragment>
    <Fragment slot="tab.apiv4">API v4</Fragment>

<Fragment slot="panel.consoleworkloads">

1. Access [Azion Console](/en/documentation/products/guides/how-to-access-azion-console/) > **Certificate Manager**.
2. Click the **+ Digital Certificate** button.
3. Give your certificate an easy-to-remember name.
4. Select the **Import Trusted CA Certificate** option.
5. In the **Private Certificate** field, paste your Trusted CA, including the begin and end tags.

:::caution[warning]
The certificate file must be in Privacy Enhanced Mail (PEM) format, which ends with the `.pem` file extension. Certificates in other formats aren't accepted.
:::

6. Click the **Save** button.

After adding a **Trusted CA** to your certificate library, you need to configure which domains should operate with mTLS.

1. Access [Azion Console](/en/documentation/products/guides/how-to-access-azion-console/) > **Workloads**.
2. Click on the workload you'd like to configure **mTLS** for.
3. Enable the **Mutual Authentication** switch.
4. Choose which verification mode you wish to use.
  - By selecting **Enforce** (default), mTLS is enabled in your application's domain and all incoming traffic will comply with client and server authentication.
  - By selecting **Permissive**, you must [configure this mode in Firewall](#creating-specific-rules-for-permissive-mtls).
5. Select the **Trusted CA Certificate** you created.
6. Click the **Save** button.

:::caution[warning]
The **Permissive** mode is recommended when testing access to your application under specific conditions. Misconfiguring the **Permissive** verification mode can result in security faults. 
:::

</Fragment>

<Fragment slot="panel.consoledomains">
1. Access [Azion Console](/en/documentation/products/guides/how-to-access-azion-console/) > **Certificate Manager**.
2. Click the **+ Digital Certificate** button.
3. Give your certificate an easy-to-remember name.
4. Select the **Import Trusted CA Certificate** option.
5. In the **Private Certificate** field, paste your Trusted CA, including the begin and end tags.

:::caution[warning]
The certificate file must be in Privacy Enhanced Mail (PEM) format, which ends with the `.pem` file extension. Certificates in other formats aren't accepted.
:::

6. Click the **Save** button.

After adding a **Trusted CA** to your certificate library, you need to configure which domains should operate with mTLS.

1. Access [Azion Console](/en/documentation/products/guides/how-to-access-azion-console/) > **Domains**.
2. Click on the domain you'd like to configure **mTLS** for.
3. Enable the **Mutual Authentication** switch.
4. Choose which verification mode you wish to use.
  - By selecting **Enforce** (default), mTLS is enabled in your application's domain and all incoming traffic will comply with client and server authentication.
  - By selecting **Permissive**, you must [configure this mode in Firewall](#creating-specific-rules-for-permissive-mtls).
5. Select the **Trusted CA Certificate** you created.
6. Click the **Save** button.

:::caution[warning]
The **Permissive** mode is recommended when testing access to your application under specific conditions. Misconfiguring the **Permissive** verification mode can result in security faults. 
:::
</Fragment>

<Fragment slot="panel.apiv4">

1. Run the following `POST` request in your terminal, replacing `[TOKEN VALUE]` with your [personal token](/en/documentation/products/guides/personal-tokens/) and the certificate in the `certificate` property:

<Code lang="bash" code={`
curl --request POST \
  --url https://api.azion.com/v4/digital_certificates/certificates \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "Trusted CA - mydomain.com",
    "type": "trusted_ca_certificate",
    "certificate": "-----BEGIN CERTIFICATE-----\nMIIDCTCCAfGgAwIBAgIJAPpKHOLMIGuAMA0GCSqGSIb3DQEBBQUAMBsxGTAXBgNV\nBAMMEHd3dy5teWRvbWFpbi5jb20wHhcNMTgwMzI3MjAwOTA0WhcNMjgwMzI0MjAw\nOTA0WjAbMRkwFwYDVQQDDBB3d3cubXlkb21haW4uY29tMIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEAt25cziDBsHbZzZhy9BPLApPf9OmE67k9pr7VezsR\nkIw4trY2xtJXFB7itT1p7HxbLBoL5u8FGmMKssB+XTmztmgty43ogor1KSjUgfZg\nrpAqyXtrbSM5g+14c0VO9S0LkkePlHvul0UiblJj7K+gkvc6sZqXZY+TI1BPqeuO\ns9A4LLCUGziyNv0qJfIL5RZm07Yy35BEBTTxUWVL2msfaUH2uPM5XN5eFC7oKN0/\n3NuYIboRmyk+P7CDC99M8Mp/wOjiB+yVGZVTjeqGPI8nFWJl2wtyuiZ4VvW84xQP\njwtid1v1KENK/ixMAAXi2cQ9gNRX+/USoneuWj5n4QUj6QIDAQABo1AwTjAdBgNV\nHQ4EFgQU2sDgtyYMDXvw79OhdvAFqcLmcwkwHwYDVR0jBBgwFoAU2sDgtyYMDXvw\n79OhdvAFqcLmcwkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAKzCM\niG67IPwJK6MIJ31N734AofjkOf+fffxNtfYmH0XGORHPYUxCxsLxXiSFgPvubWh+\n7vLsKAm67bflMWbn982aiOR0O/LJhLvhj6F+wgv0aDYup181Hm8Ob/88ldbF6ND1\nTqzVATS0WDfl+z1QBKtNdDm3Nv45IZ83ob7OhIzD9MwL6tflBPDpWOYtmBDn0xSP\n6ra9d8oa6jK1fe2/5A7LY41acjbbNrLbFDYP7hcx02TmCfSMut+ysaZ/blay4Sbb\nwNlt92KhJw07UEKgXXbgyXGoFQkU8V+r2AZcgt0XM9jvwTc01Sbq/gegd2GMAj3x\nrTwkn5UNzFs56FCgNg==\n-----END CERTIFICATE-----",
    "active": true
  }'
`} />


| Key | Description |
| --- | --- |
| `name` | Name of the certificate instance |
| `certificate` | String that holds the certificate value. Must include the begin and end tags. Line feeds must be replaced by escape sequences (`\n`) |
| `type` | Enum that indicates the type of the certificate. Trusted CA certificates are assigned the value `trusted_ca_certificate` |

1. You'll receive a response similar to this:

<Code lang="json" code={`
{
    "results": {
        "id": <digital_certificate_id>,
        "name": "Trusted CA - mydomain.com",
        "issuer": "CA name",
        "subject_name": [],
        "validity": "2028-03-24 20:09:00-03:00",
        "status": "Active",
        "certificate_type": "trusted_ca_certificate",
        "managed": false
    }
}
`} />

3. Copy the `digital_certificate_id` value. You'll need it while associating it with a Workload.
4. Run the following `POST` request in your terminal, replacing `[TOKEN VALUE]` with your [personal token](/en/documentation/products/guides/personal-tokens/), the `<application_id>` with an application ID, and the `<digital_certificate_id>` with the ID of the Trusted CA you created:

<Code lang="bash" code={`
curl --request POST \
  --url https://api.azion.com/v4/workspace/workloads \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "mydomain.com",
    "active": true,
    "infrastructure": 1,
    "domains": ["mydomain.com"],
    "protocols": {
      "http": {
        "versions": ["http1", "http2"],
        "http_ports": [80],
        "https_ports": [443]
      }
    },
    "mtls": {
      "verification": "enforce",
      "certificate": <digital_certificate_id>
    },
    "workload_domain_allow_access": true
  }'
`} />

| Key | Description |
| --- | --- |
| `name` | Name of the domain instance |
| `cnames` | Accepts an array of strings containing the CNAMEs for the domain as values |
| `digital_certificate_id` | Enum that, when `null`, selects the **Azion SAN** certificate |
| `edge_application_id` | The [ID of the application](/en/documentation/products/guides/build/build-an-application/) linked to the domain |
| `is_mtls_enabled` | Boolean that, when `true`, activates mTLS verification for the domain |
| `mtls_verification` | Enum that sets the verification mode. Can be `enforce` or `permissive` |
| `mtls_trusted_ca_certificate_id` | The [ID of the Trusted CA](#adding-a-trusted-ca-certificate-and-associating-it-to-a-domain) |

5. You'll receive a response similar to this:

<Code lang="json" code={`
{
  "state": "executed",
  "data": {
    "id": 987654321,
    "name": "mydomain.com",
    "active": true,
    "last_editor": "api_user@example.com",
    "last_modified": "2025-08-20T12:34:56Z",
    "infrastructure": 1,
    "tls": {
      "certificate": null,
      "minimum_version": "tls_1_2",
      "ciphers": 4
    },
    "protocols": {
      "http": {
        "versions": ["http1", "http2"],
        "http_ports": [80],
        "https_ports": [443],
        "quic_ports": []
      }
    },
    "mtls": {
      "verification": "enforce",
      "certificate": 123456789,
      "crl": []
    },
    "domains": ["mydomain.com"],
    "workload_domain_allow_access": true,
    "workload_domain": "",
    "product_version": "1.0"
  }
}
`} />


6. Run the following `POST` request in your terminal to bind your new workload to an application, replacing `[TOKEN VALUE]` with your [personal token](/en/documentation/products/guides/personal-tokens/), the `<application_id>` with an application ID, and the `<workload_id>` with the ID of the workload you created:

<Code lang="bash" code={`
curl --request POST \
  --url https://api.azion.com/v4/workspace/workloads/<workload_id>/deployments \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "My Workload Deployment",
  "current": true,
  "active": true,
  "strategy": {
    "type": "string",
    "attributes": {
      "edge_application": <application_id>,
    }
  }
}'

`} />


7. Wait for the propagation time. Your domain should now be using the mTLS protocol.


</Fragment>

<Fragment slot="panel.apiv3">
1. Run the following `POST` request in your terminal, replacing `[TOKEN VALUE]` with your [personal token](/en/documentation/products/guides/personal-tokens/) and the certificate in the `certificate` property:

<Code lang="bash" code={`
curl --location 'https://api.azionapi.net/digital_certificates' \
--header 'Accept: application/json; version=3' \
--header 'Authorization: Token [TOKEN VALUE]' \
--header 'Content-Type: application/json' \
--data '{
    "name": "Trusted CA - mydomain.com",
    "certificate": "-----BEGIN CERTIFICATE-----\nMIIDCTCCAfGgAwIBAgIJAPpKHOLMIGuAMA0GCSqGSIb3DQEBBQUAMBsxGTAXBgNV\nBAMMEHd3dy5teWRvbWFpbi5jb20wHhcNMTgwMzI3MjAwOTA0WhcNMjgwMzI0MjAw\nOTA0WjAbMRkwFwYDVQQDDBB3d3cubXlkb21haW4uY29tMIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEAt25cziDBsHbZzZhy9BPLApPf9OmE67k9pr7VezsR\nkIw4trY2xtJXFB7itT1p7HxbLBoL5u8FGmMKssB+XTmztmgty43ogor1KSjUgfZg\nrpAqyXtrbSM5g+14c0VO9S0LkkePlHvul0UiblJj7K+gkvc6sZqXZY+TI1BPqeuO\ns9A4LLCUGziyNv0qJfIL5RZm07Yy35BEBTTxUWVL2msfaUH2uPM5XN5eFC7oKN0/\n3NuYIboRmyk+P7CDC99M8Mp/wOjiB+yVGZVTjeqGPI8nFWJl2wtyuiZ4VvW84xQP\njwtid1v1KENK/ixMAAXi2cQ9gNRX+/USoneuWj5n4QUj6QIDAQABo1AwTjAdBgNV\nHQ4EFgQU2sDgtyYMDXvw79OhdvAFqcLmcwkwHwYDVR0jBBgwFoAU2sDgtyYMDXvw\n79OhdvAFqcLmcwkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAKzCM\niG67IPwJK6MIJ31N734AofjkOf+fffxNtfYmH0XGORHPYUxCxsLxXiSFgPvubWh+\n7vLsKAm67bflMWbn982aiOR0O/LJhLvhj6F+wgv0aDYup181Hm8Ob/88ldbF6ND1\nTqzVATS0WDfl+z1QBKtNdDm3Nv45IZ83ob7OhIzD9MwL6tflBPDpWOYtmBDn0xSP\n6ra9d8oa6jK1fe2/5A7LY41acjbbNrLbFDYP7hcx02TmCfSMut+ysaZ/blay4Sbb\nwNlt92KhJw07UEKgXXbgyXGoFQkU8V+r2AZcgt0XM9jvwTc01Sbq/gegd2GMAj3x\nrTwkn5UNzFs56FCgNg==\n-----END CERTIFICATE-----",
    "certificate_type": "trusted_ca_certificate"
}'
`} />


| Key | Description |
| --- | --- |
| `name` | Name of the certificate instance |
| `certificate` | String that holds the certificate value. Must include the begin and end tags. Line feeds must be replaced by escape sequences (`\n`) |
| `certificate_type` | Enum that indicates the type of the certificate. Trusted CA certificates are assigned the value `trusted_ca_certificate` |

2. You'll receive a response similar to this:

<Code lang="json" code={`
{
    "results": {
        "id": <digital_certificate_id>,
        "name": "Trusted CA - mydomain.com",
        "issuer": "CA name",
        "subject_name": [],
        "validity": "2028-03-24 20:09:00-03:00",
        "status": "Active",
        "certificate_type": "trusted_ca_certificate",
        "managed": false
    }
}
`} />

3. Copy the `digital_certificate_id` value. You'll need it while associating it with a domain.
4. Run the following `POST` request in your terminal, replacing `[TOKEN VALUE]` with your [personal token](/en/documentation/products/guides/personal-tokens/), the `<application_id>` with an application ID, and the `<digital_certificate_id>` with the ID of the Trusted CA you created:

<Code lang="bash" code={`
curl --location 'https://api.azionapi.net/domains' \
--header 'Accept: application/json; version=3' \
--header 'Authorization: Token [TOKEN VALUE]' \
--header 'Content-Type: application/json' \
--data '{
    "name": "mydomain.com",
    "cnames": [
        "mydomain.com"
    ],
    "digital_certificate_id": null,
    "edge_application_id": <application_id>,
    "is_mtls_enabled": true,
    "mtls_verification": "enforce",
    "mtls_trusted_ca_certificate_id": <digital_certificate_id>
}'
`} />


| Key | Description |
| --- | --- |
| `name` | Name of the domain instance |
| `cnames` | Accepts an array of strings containing the CNAMEs for the domain as values |
| `digital_certificate_id` | Enum that, when `null`, selects the **Azion SAN** certificate |
| `edge_application_id` | The [ID of the application](/en/documentation/products/guides/build/build-an-application/) linked to the domain |
| `is_mtls_enabled` | Boolean that, when `true`, activates mTLS verification for the domain |
| `mtls_verification` | Enum that sets the verification mode. Can be `enforce` or `permissive` |
| `mtls_trusted_ca_certificate_id` | The [ID of the Trusted CA](#adding-a-trusted-ca-certificate-and-associating-it-to-a-domain) |

5. You'll receive a response similar to this:

<Code lang="json" code={`
{
    "id": <domain_id>,
    "name": "mydomain.com",
    "cnames": [
        "mydomain.com"
    ],
    "cname_access_only": true,
    "digital_certificate_id": null,
    "edge_application_id": <application_id>,
    "is_active": true,
    "domain_name": "abcde12345.map.azionedge.net",
    "environment": "production",
    "is_mtls_enabled": true,
    "mtls_verification": "enforce",
    "mtls_trusted_ca_certificate_id": <digital_certificate_id>,
    "edge_firewall_id": null
}
`} />


6. Wait for the propagation time. Your domain should now be using the mTLS protocol.
</Fragment>

</Tabs>

---

## Creating specific rules for Permissive mTLS

To configure a firewall to block access to a domain using the **Permissive** mode in mTLS, you must use the [Rules Engine for Firewall](/en/documentation/products/secure/firewall/rules-engine/). The following example describes a rule set that will block any incoming network traffic with the hostname `mydomain.com` whose client certificate validation isn't true and deliver a `403 Forbidden` error.

<Tabs client:visible>
    <Fragment slot="tab.console">Console</Fragment>
    <Fragment slot="tab.api">API</Fragment>

<Fragment slot="panel.console">

1. Access [Azion Console](/en/documentation/products/guides/how-to-access-azion-console/) > **Firewall**.
2. [Configure an firewall](/en/documentation/products/guides/secure/firewall-configure-main-settings/) for the mTLS domain.
3. Click the **Rules Engine** tab.
4. Click the **+ Rules Engine** button.
5. Give your rule an easy-to-remember name.
6. In the **Criteria** section, as a variable, select **Host**.
7. As a comparison operator, select **is equal**.
8. As an argument, enter `mydomain.com`.
9. Click the **+ And** button to add a new criteria.
10. As a variable, select **Client Certificate Validation**.
11. As a comparison operator, select **is not equal to**.
12. As an argument, enter `true`.
13. In the **Behavior** section, select **Deny (403 Forbidden)**.
14. Click the **Save** button.

</Fragment>

<Fragment slot="panel.api">

1. Run the following `POST` request in your terminal, replacing `[TOKEN VALUE]` with your [personal token](/en/documentation/products/guides/personal-tokens/) and the `<edge_firewall_id>` with the ID of the firewall associated with the mTLS domain:

<Code lang="bash" code={`
curl --request POST \
  --url https://api.azion.com/v4/edge_firewall/firewalls/<edge_firewall_id>/request_rules \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "403 Host=mydomain.com and CCV!=true",
    "description": "Delivers a 403 if the hostname does not match mydomain.com and if the certificate validation fails.",
    "active": true,
    "criteria": [
      [
        {
          "conditional": "if",
          "variable": "\${host}",
          "operator": "is_equal",
          "argument": "mydomain.com"
        },
        {
          "conditional": "and",
          "variable": "\${client_certificate_validation}",
          "operator": "is_not_equal",
          "argument": "true"
        }
      ]
    ],
    "behaviors": [
      { "type": "deny" }
    ]
  }'
`} />


| Key | Description |
| --- | --- |
| `name` | Name of the rule |
| `description` | Description of the rule |
| `behaviors` | Array that stores objects that define behaviors |
| `criteria` | Array that stores objects that define criteria |

1. You'll receive a response similar to this:

<Code lang="json" code={`
{
  "results": {
      "name": "403 Host=mydomain.com and CCV!=true",
      "description": "Delivers a 403 if the hostname does not match mydomain.com and if the certificate validation fails.",
      "behaviors": [
          {
              "name": "deny"
          }
      ],
      "criteria": [
          [
              {
                  "variable": "host",
                  "operator": "is_equal",
                  "conditional": "if",
                  "argument": "mydomain.com"
              },
              {
                  "variable": "client_certificate_validation",
                  "operator": "is_not_equal",
                  "conditional": "and",
                  "argument": "true"
              }
          ]
      ],
      "id": <rule_set_id>,
      "order": 0
  }
}
`} />

</Fragment>

</Tabs>

---

## Specifying mTLS variables in HTTP headers

If your application is part of the Open Banking model, you must specify the variables `${ssl_client_escaped_cert}` and `${ssl_client_s_dn_parsed}` in the HTTP headers of your application. You can use the [Rules Engine for Application](/en/documentation/products/build/applications/rules-engine/) to create this behavior for your whole application.

Requires:

- <Tag severity="info">[Application Accelerator](/en/documentation/products/guides/build/configure-main-settings/#modules)</Tag>
- <Tag severity="info">[Domain with an mTLS certificate](#add-a-trusted-ca-certificate-and-associate-it-to-a-domain)</Tag>

:::tip
You can also insert headers with other variables from [the list of available mTLS variables](/en/documentation/products/build/applications/rules-engine/#mutual-transport-layer-security-mtls-variables).
:::

To test whether the headers you add are being sent in requests, you can run the following cURL command in your terminal from a directory containing the `.pem` files of your Trusted CA and its private key:

```bash
curl -skv https://mydomain.com/ -H "Pragma: azion-debug-cache" -o /dev/stdout --cert cert.pem --key key.pem
```
<Tabs client:visible>
    <Fragment slot="tab.console">Console</Fragment>
    <Fragment slot="tab.api">API</Fragment>

<Fragment slot="panel.console">

1. Access [Azion Console](/en/documentation/products/guides/how-to-access-azion-console/) > **Application**.
2. Find and click on the application with the mTLS domain.
3. Click the **Rules Engine** tab.
4. Click the **+ Rule** button.
5. Give your rule an easy-to-remember name.
6. Select **Request Phase**.
7. In the **Criteria** field, enter the desired mTLS variable. Example: `${ssl_client_escaped_cert}`.
8. Select the comparison operator **exists**.
9. In the **Behaviors** section, select the **Add Response Header** behavior.
10. As an argument, enter `Mtls-Variable-Name: ${ssl_variable_name}`, replacing the name and variable with the mTLS variable you wish to insert in your application's header.
    - Example: `Escaped-Client-Cert: ${ssl_client_escaped_cert}`

:::note
The use of the prefix `X-` in the header name of custom HTTP variables is discouraged by the Internet Engineering Task Force (IETF) under [RFC 6648](https://datatracker.ietf.org/doc/rfc6648/). The IETF recommends using a simple `Header-Name` format to indicate the actual use of the variable.
:::

11. To add another variable, click the **+ And** button in the **Criteria** section and repeat the remaining steps.
12. Click the **Save** button when you're done.
</Fragment>

<Fragment slot="panel.api">
1. Run the following `POST` request in your terminal, replacing `[TOKEN VALUE]` with your [personal token](/en/documentation/products/guides/personal-tokens/) and the `<application_id>` with the ID of the application associated with the mTLS domain:

<Code lang="bash" code={`
curl --request POST \
  --url https://api.azion.com/v4/edge_application/applications/<application_id>/request_rules \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
    "name": "mTLS variables",
    "description": "Adds certificate values according to Open Banking standards",
    "active": true,
    "criteria": [
      [
        {
          "conditional": "if",
          "variable": "\${ssl_client_escaped_cert}",
          "operator": "exists",
          "argument": ""
        }
      ]
    ],
    "behaviors": [
      {
        "type": "add_request_header",
        "attributes": {
          "name": "Escaped-Client-Cert",
          "value": "\${ssl_client_escaped_cert}"
        }
      }
    ]
  }'
`} />


1. You'll receive a response similar to this:

<Code lang="json" code={`

{
  "results": {
      "id": <rule_id>,
      "name": "mTLS variables",
      "phase": "request",
      "behaviors": [
          {
              "name": "add_request_header",
              "target": "Escaped-Client-Cert: \${ssl_client_escaped_cert}"
          }
      ],
      "criteria": [
          [
              {
                  "variable": "\${ssl_client_escaped_cert}",
                  "operator": "exists",
                  "conditional": "if",
                  "input_value": ""
              }
          ]
      ],
      "description": "Adds certificate values according to Open Banking standards"
  }
}
`} />


3. Repeat the previous step for each mTLS variable required in the headers.

</Fragment>

</Tabs>
---