diff --git a/src/content/docs/cloudflare-one/access-controls/service-credentials/mutual-tls-authentication.mdx b/src/content/docs/cloudflare-one/access-controls/service-credentials/mutual-tls-authentication.mdx index 652c546b0efc81..d0d09a11530909 100644 --- a/src/content/docs/cloudflare-one/access-controls/service-credentials/mutual-tls-authentication.mdx +++ b/src/content/docs/cloudflare-one/access-controls/service-credentials/mutual-tls-authentication.mdx @@ -354,6 +354,8 @@ You can use the Cloudflare PKI toolkit to generate a certificate revocation list You will need to add the CRL to your server or enforce the revocation in a Cloudflare Worker. An example Worker Script can be found on the [Cloudflare GitHub repository](https://github.com/cloudflare/access-crl-worker-template). + + ## Known limitations @@ -370,5 +372,4 @@ Cloudflare will send the following [notifications](/notifications/) before your - +/> \ No newline at end of file diff --git a/src/content/docs/learning-paths/mtls/mtls-workers/index.mdx b/src/content/docs/learning-paths/mtls/mtls-workers/index.mdx index 3802337da6c7f0..43c3d803212bf2 100644 --- a/src/content/docs/learning-paths/mtls/mtls-workers/index.mdx +++ b/src/content/docs/learning-paths/mtls/mtls-workers/index.mdx @@ -15,7 +15,7 @@ Cloudflare Workers runs after the Cloudflare WAF and Cloudflare Access. Review t ## Expose mTLS headers -All Client Certificate details can be found in the [tlsClientAuth](/workers/runtime-apis/request#incomingrequestcfproperties) object in Cloudflare Workers. +All Client Certificate details can be found in the [tlsClientAuth](/workers/runtime-apis/request#incomingrequestcfproperties) object in Cloudflare Workers. Refer to [Client certificate variables](/ssl/client-certificates/client-certificate-variables/) for a full list of available properties. Example Cloudflare Workers code to return all headers and gain visibility, including [Client Certificate headers](/ssl/client-certificates/forward-a-client-certificate/#cloudflare-workers): @@ -105,4 +105,4 @@ The response when using the browser with a P12 Certificate to visit the mTLS hos The client certificate serial number is a unique identifier assigned to each certificate by the CA, ensuring that no two certificates issued by the same CA have the same serial number. This can be useful to track and monitor certificate usage or abuse. ::: -This approach can also be useful to handle additional checks and logic on the mTLS via the Cloudflare Workers. +This approach can also be useful to handle additional checks and logic on the mTLS via the Cloudflare Workers. \ No newline at end of file diff --git a/src/content/docs/ssl/client-certificates/client-certificate-variables.mdx b/src/content/docs/ssl/client-certificates/client-certificate-variables.mdx new file mode 100644 index 00000000000000..c0c2511f65b181 --- /dev/null +++ b/src/content/docs/ssl/client-certificates/client-certificate-variables.mdx @@ -0,0 +1,42 @@ +--- +pcx_content_type: reference +title: Client certificate variables +sidebar: + order: 10 +--- + +When a request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/), Cloudflare exposes certificate details as variables in the Ruleset Engine and as properties on the Workers `request.cf` object. + +## Ruleset Engine fields + +Client certificate fields are available as [mTLS fields](/ruleset-engine/rules-language/fields/reference/?field-category=mTLS) in Ruleset Engine-based products such as [WAF custom rules](/waf/custom-rules/) and [request header modification rules](/rules/transform/request-header-modification/). + +## Workers variables + +These variables are also available as part of the [`request.cf.tlsClientAuth`](/workers/runtime-apis/request/#incomingrequestcfproperties) object via Cloudflare Workers. See the linked Ruleset field for the definition. + +:::note +Some tlsClientAuth properties have a different type than their Ruleset field equivalent. Those are called out below. +::: + +- [`request.cf.tlsClientAuth.certRevoked`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_revoked/) — In Workers, this is a string (`"1"` for revoked, `"0"` for not revoked) rather than a boolean. +- [`request.cf.tlsClientAuth.certVerified`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_verified/) — In Workers, this is a string (`"SUCCESS"` when valid, `"NONE"` when not present) rather than a boolean. On failure, the string contains the error reason (for example, `"FAILED:unable to get local issuer certificate"`). +- [`request.cf.tlsClientAuth.certPresented`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_presented/) — In Workers, this is a string (`"1"` when a certificate is presented, `"0"` otherwise) rather than a boolean. +- [`request.cf.tlsClientAuth.certIssuerDN`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_issuer_dn/) +- [`request.cf.tlsClientAuth.certSubjectDN`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_subject_dn/) +- [`request.cf.tlsClientAuth.certIssuerDNRFC2253`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_issuer_dn_rfc2253/) +- [`request.cf.tlsClientAuth.certSubjectDNRFC2253`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_subject_dn_rfc2253/) +- [`request.cf.tlsClientAuth.certIssuerDNLegacy`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_issuer_dn_legacy/) +- [`request.cf.tlsClientAuth.certSubjectDNLegacy`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_subject_dn_legacy/) +- [`request.cf.tlsClientAuth.certSerial`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_serial/) +- [`request.cf.tlsClientAuth.certIssuerSerial`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_issuer_serial/) +- [`request.cf.tlsClientAuth.certFingerprintSHA256`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_fingerprint_sha256/) +- [`request.cf.tlsClientAuth.certFingerprintSHA1`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_fingerprint_sha1/) +- [`request.cf.tlsClientAuth.certNotBefore`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_not_before/) +- [`request.cf.tlsClientAuth.certNotAfter`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_not_after/) +- [`request.cf.tlsClientAuth.certSKI`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_ski/) +- [`request.cf.tlsClientAuth.certIssuerSKI`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_issuer_ski/) +- [`request.cf.tlsClientAuth.certRFC9440`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_rfc9440/) +- [`request.cf.tlsClientAuth.certRFC9440TooLarge`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_rfc9440_too_large/) +- [`request.cf.tlsClientAuth.certChainRFC9440`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_chain_rfc9440/) +- [`request.cf.tlsClientAuth.certChainRFC9440TooLarge`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_chain_rfc9440_too_large/) diff --git a/src/content/docs/ssl/client-certificates/forward-a-client-certificate.mdx b/src/content/docs/ssl/client-certificates/forward-a-client-certificate.mdx index 507cd2bab2d09c..b402bae889b640 100644 --- a/src/content/docs/ssl/client-certificates/forward-a-client-certificate.mdx +++ b/src/content/docs/ssl/client-certificates/forward-a-client-certificate.mdx @@ -5,8 +5,8 @@ sidebar: order: 6 --- -Customers using [Cloudflare Access](/cloudflare-one/access-controls/policies/) also have the option to forward client certificates to their origin server. - import { Render } from "~/components"; - + + + \ No newline at end of file diff --git a/src/content/docs/ssl/client-certificates/troubleshooting.mdx b/src/content/docs/ssl/client-certificates/troubleshooting.mdx index 80c47a027b76f9..5275e5cb31e675 100644 --- a/src/content/docs/ssl/client-certificates/troubleshooting.mdx +++ b/src/content/docs/ssl/client-certificates/troubleshooting.mdx @@ -3,7 +3,7 @@ title: Troubleshooting pcx_content_type: troubleshooting description: Troubleshoot issues with client certificates sidebar: - order: 10 + order: 11 head: - tag: title content: Troubleshooting client certificates @@ -110,4 +110,3 @@ You can use [Cloudflare Workers](/workers/) to debug client certificate validati "certVerified": "NONE", }, ``` - diff --git a/src/content/docs/ssl/client-certificates/zero-trust-mtls.mdx b/src/content/docs/ssl/client-certificates/zero-trust-mtls.mdx index a3b428c4af9b24..e277d8af70c03f 100644 --- a/src/content/docs/ssl/client-certificates/zero-trust-mtls.mdx +++ b/src/content/docs/ssl/client-certificates/zero-trust-mtls.mdx @@ -4,5 +4,4 @@ title: mTLS for Zero Trust external_link: /cloudflare-one/access-controls/service-credentials/mutual-tls-authentication/ sidebar: order: 14 - ---- +--- \ No newline at end of file diff --git a/src/content/docs/workers/runtime-apis/request.mdx b/src/content/docs/workers/runtime-apis/request.mdx index 5fa8ad7d86058e..a706a352baf61f 100644 --- a/src/content/docs/workers/runtime-apis/request.mdx +++ b/src/content/docs/workers/runtime-apis/request.mdx @@ -257,7 +257,7 @@ All plans have access to: * `tlsClientAuth` Object | null - * Only set when using Cloudflare Access or API Shield (mTLS). Object with the following properties: `certFingerprintSHA1`, `certFingerprintSHA256`, `certIssuerDN`, `certIssuerDNLegacy`, `certIssuerDNRFC2253`, `certIssuerSKI`, `certIssuerSerial`, `certNotAfter`, `certNotBefore`, `certPresented`, `certRevoked`, `certSKI`, `certSerial`, `certSubjectDN`, `certSubjectDNLegacy`, `certSubjectDNRFC2253`, `certVerified`. + * Various details about the client certificate (for mTLS connections). Refer to [Client certificate variables](/ssl/client-certificates/client-certificate-variables/) for more details. * `tlsClientCiphersSha1` string @@ -454,4 +454,4 @@ Incoming `Request` objects passed to the [`fetch()` handler](/workers/runtime-ap * [Examples: Modify request property](/workers/examples/modify-request-property/) * [Examples: Accessing the `cf` object](/workers/examples/accessing-the-cloudflare-object/) * [Reference: `Response`](/workers/runtime-apis/response/) -* Write your Worker code in [ES modules syntax](/workers/reference/migrate-to-module-workers/) for an optimized experience. +* Write your Worker code in [ES modules syntax](/workers/reference/migrate-to-module-workers/) for an optimized experience. \ No newline at end of file diff --git a/src/content/fields/index.yaml b/src/content/fields/index.yaml index 9978a1c6889307..3be63a2a289f65 100644 --- a/src/content/fields/index.yaml +++ b/src/content/fields/index.yaml @@ -672,37 +672,37 @@ entries: data_type: Boolean categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: Indicates whether the request presented a valid but revoked client certificate. + summary: Indicates whether the mTLS client presented a valid but revoked client certificate. description: |- When `true`, the [`cf.tls_client_auth.cert_verified`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_verified/) field is also `true`. - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `false` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). - name: cf.tls_client_auth.cert_verified data_type: Boolean categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: Returns `true` when a request presents a valid client certificate. + summary: Returns `true` when a mTLS client presents a valid client certificate. description: |- - Also returns `true` when a request includes a valid certificate that was revoked (refer to [`cf.tls_client_auth.cert_revoked`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_revoked/)). + Also returns `true` when a client presents a valid certificate that was revoked (refer to [`cf.tls_client_auth.cert_revoked`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_revoked/)). - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `false` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). - name: cf.tls_client_auth.cert_presented data_type: Boolean categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: Returns `true` when a request presents a certificate (valid or not). + summary: Returns `true` when a mTLS client presents a certificate (valid or not). description: |- - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `false` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). - name: cf.tls_client_auth.cert_issuer_dn data_type: String categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: The Distinguished Name (DN) of the Certificate Authority (CA) that issued the certificate included in the request. + summary: The Distinguished Name (DN) of the Certificate Authority (CA) that issued the mTLS client certificate. description: |- - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `""` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). example_value: |- "CN=Access Testing CA,OU=TX,O=Access Testing,L=Austin,ST=Texas,C=US" @@ -710,9 +710,9 @@ entries: data_type: String categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: The Distinguished Name (DN) of the owner (or requester) of the certificate included in the request. + summary: The Distinguished Name (DN) of the owner (or requester) of the mTLS client certificate. description: |- - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `""` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). example_value: |- "CN=James Royal,OU=Access Admins,O=Access,L=Austin,ST=Texas,C=US" @@ -720,9 +720,9 @@ entries: data_type: String categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: The Distinguished Name (DN) of the Certificate Authority (CA) that issued the certificate in the request in [RFC 2253](https://datatracker.ietf.org/doc/html/rfc2253) format. + summary: The Distinguished Name (DN) of the Certificate Authority (CA) that issued the mTLS client certificate in [RFC 2253](https://datatracker.ietf.org/doc/html/rfc2253) format. description: |- - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `""` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). example_value: |- "CN=Access Testing CA,OU=TX,O=Access Testing,L=Austin,ST=Texas,C=US" @@ -730,9 +730,9 @@ entries: data_type: String categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: The Distinguished Name (DN) of the owner (or requester) of the certificate in the request in [RFC 2253](https://datatracker.ietf.org/doc/html/rfc2253) format. + summary: The Distinguished Name (DN) of the owner (or requester) of the mTLS client certificate in [RFC 2253](https://datatracker.ietf.org/doc/html/rfc2253) format. description: |- - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `""` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). example_value: |- "CN=James Royal,OU=Access Admins,O=Access,L=Austin,ST=Texas,C=US" @@ -740,9 +740,9 @@ entries: data_type: String categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: The Distinguished Name (DN) of the Certificate Authority (CA) that issued the certificate in the request in a legacy format. + summary: The Distinguished Name (DN) of the Certificate Authority (CA) that issued the mTLS client certificate in a legacy format. description: |- - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `""` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). example_value: |- "/C=US/ST=Texas/L=Austin/O=Access Testing/OU=TX/CN=Access Testing CA" @@ -750,9 +750,9 @@ entries: data_type: String categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: The Distinguished Name (DN) of the owner (or requester) of the certificate in the request in a legacy format. + summary: The Distinguished Name (DN) of the owner (or requester) of the mTLS client certificate in a legacy format. description: |- - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `""` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). example_value: |- "/C=US/ST=Texas/L=Austin/O=Access/OU=Access Admins/CN=James Royal" @@ -760,9 +760,9 @@ entries: data_type: String categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: Serial number of the certificate in the request. + summary: Serial number of the mTLS client certificate. description: |- - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `""` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). example_value: |- "527E0F20A20EA2A4146C78390F34CE7AF0878CA4" @@ -770,9 +770,9 @@ entries: data_type: String categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: Serial number of the direct issuer of the certificate in the request. + summary: Serial number of the direct issuer of the mTLS client certificate. description: |- - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `""` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). example_value: |- "2688201DBA77402EA87118876F2E1B24CF8B0395" @@ -780,9 +780,9 @@ entries: data_type: String categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: The SHA-256 fingerprint of the certificate in the request. + summary: The SHA-256 fingerprint of the mTLS client certificate. description: |- - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `""` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). example_value: |- "af363dc85bc942a892d3cee9796190fdb36d89cd588a4f1cb17c74a943439714" @@ -790,9 +790,9 @@ entries: data_type: String categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: The SHA-1 fingerprint of the certificate in the request. + summary: The SHA-1 fingerprint of the mTLS client certificate. description: |- - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `""` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). example_value: |- "933ad5282c560ae3f482a43ecd73bc9de878a190" @@ -800,9 +800,9 @@ entries: data_type: String categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: The certificate in the request is not valid before this date. + summary: The mTLS client certificate is not valid before this date. description: |- - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `""` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). example_value: |- "Mar 21 13:35:00 2022 GMT" @@ -810,9 +810,9 @@ entries: data_type: String categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: The certificate in the request is not valid after this date. + summary: The mTLS client certificate is not valid after this date. description: |- - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `""` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). example_value: |- "Mar 21 13:35:00 2023 GMT" @@ -820,9 +820,9 @@ entries: data_type: String categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: The Subject Key Identifier (SKI) of the certificate in the request. + summary: The Subject Key Identifier (SKI) of the mTLS client certificate. description: |- - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `""` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). example_value: |- "27846FAE6EAC4A8DAD9101B519CF1EB460242831" @@ -830,12 +830,64 @@ entries: data_type: String categories: [Request, mTLS] keywords: [request, ssl, mtls, client, visitor] - summary: The Subject Key Identifier (SKI) of the direct issuer of the certificate in the request. + summary: The Subject Key Identifier (SKI) of the direct issuer of the mTLS client certificate. description: |- - This field is only filled in if the request includes a client certificate for [mTLS authentication](/ssl/client-certificates/enable-mtls/). + This field defaults to `""` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). example_value: |- "8204924CF49D471E855862706D889F58F6B784D3" + - name: cf.tls_client_auth.cert_rfc9440 + data_type: String + categories: [Request, mTLS] + keywords: [request, ssl, mtls, client, visitor, rfc9440, cert, chain] + summary: The mTLS client certificate encoded as a structured field byte sequence per [RFC 9440](https://datatracker.ietf.org/doc/html/rfc9440). + description: |- + Contains the DER-encoded, Base64-wrapped client leaf certificate formatted as an [RFC 9440](https://datatracker.ietf.org/doc/html/rfc9440#name-client-cert-http-header-fie) `Client-Cert` HTTP header value. The value is a structured field byte sequence (the Base64 data prefixed and suffixed by `:`). + + This field is populated regardless of the certificate validation result. Before using this value, verify the certificate status by checking [`cf.tls_client_auth.cert_verified`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_verified/) and [`cf.tls_client_auth.cert_revoked`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_revoked/). + + Returns `""` if no client certificate was presented or if the encoded value exceeds the 10 KiB size limit. Refer to [`cf.tls_client_auth.cert_rfc9440_too_large`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_rfc9440_too_large/) to distinguish between these cases. + + This field defaults to `""` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). + example_value: |- + ":MIIBqDCCAU6gAwIBAgIBBzAKBggqhkjOPQQDAjA6MRswGQYDVQQLDBJDb25mb3JtYW5jZSBUZXN0aW5nMRswGQYDVQQKDBJFeGFtcGxlIENBIFByb3ZpZGVyMB4XDTI0MDEwMTAwMDAwMFoXDTI1MDEwMTAwMDAwMFowHDEaMBgGA1UEAwwRY2xpZW50LmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEE...=:" + + - name: cf.tls_client_auth.cert_rfc9440_too_large + data_type: Boolean + categories: [Request, mTLS] + keywords: [request, ssl, mtls, client, visitor, rfc9440, cert, chain, too large, error] + summary: Returns `true` when the RFC 9440 encoded mTLS client certificate exceeds the 10 KiB size limit. + description: |- + When `true`, [`cf.tls_client_auth.cert_rfc9440`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_rfc9440/) contains an empty string instead of the encoded certificate. + + This field defaults to `false` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). + + - name: cf.tls_client_auth.cert_chain_rfc9440 + data_type: String + categories: [Request, mTLS] + keywords: [request, ssl, mtls, client, visitor, rfc9440, cert, chain] + summary: The mTLS client certificate chain (excluding the leaf certificate) encoded as a structured field list per [RFC 9440](https://datatracker.ietf.org/doc/html/rfc9440). + description: |- + Contains the DER-encoded, Base64-wrapped client certificate chain formatted as an [RFC 9440](https://datatracker.ietf.org/doc/html/rfc9440#name-client-cert-chain-http-head) `Client-Cert-Chain` HTTP header value. The value is a structured field list of byte sequences. The leaf certificate is not included in the chain (it is available in [`cf.tls_client_auth.cert_rfc9440`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_rfc9440/)). The chain reflects the certificates as sent by the client, without any reordering or validation. + + This field is populated regardless of the certificate validation result. Before using this value, verify the certificate status by checking [`cf.tls_client_auth.cert_verified`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_verified/) and [`cf.tls_client_auth.cert_revoked`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_revoked/). + + Returns `""` if the client did not send any intermediate certificates or if the encoded value exceeds the 16 KiB size limit. Refer to [`cf.tls_client_auth.cert_chain_rfc9440_too_large`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_chain_rfc9440_too_large/) to distinguish between these cases. + + This field defaults to `""` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). + example_value: |- + ":MIIB8jCCAZmgAwIBAgIBBjAKBggqhkjOPQQDAjBIMRswGQYDVQQLDBJDb25mb3JtYW5jZSBUZXN0aW5nMRswGQYDVQQKDBJFeGFtcGxlIENBIFByb3ZpZGVy...=:, :MIIBqDCCAU6gAwIBAgIBAzAKBggqhkjOPQQDAjBIMRswGQYDVQQLDBJDb25mb3JtYW5jZSBUZXN0aW5nMRswGQYDVQQKDBJFeGFtcGxlIENBIFByb3ZpZGVy...=:" + + - name: cf.tls_client_auth.cert_chain_rfc9440_too_large + data_type: Boolean + categories: [Request, mTLS] + keywords: [request, ssl, mtls, client, visitor, rfc9440, cert, chain, too large, error] + summary: Returns `true` when the RFC 9440 encoded client certificate chain exceeds the 16 KiB size limit. + description: |- + When `true`, [`cf.tls_client_auth.cert_chain_rfc9440`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_chain_rfc9440/) contains an empty string instead of the encoded certificate chain. + + This field defaults to `false` if the connection does not use [mTLS authentication](/ssl/client-certificates/enable-mtls/). + - name: cf.tls_client_extensions_sha1 data_type: String categories: [Request, SSL/TLS] @@ -2205,4 +2257,4 @@ entries: You can use this field to customize the response for a specific type of error (for example, all 1XXX errors or all WAF block actions). - **Note**: This field is only available in [Response Header Transform Rules](/rules/transform/response-header-modification/) and [Custom Errors](/rules/custom-errors/). + **Note**: This field is only available in [Response Header Transform Rules](/rules/transform/response-header-modification/) and [Custom Errors](/rules/custom-errors/). \ No newline at end of file diff --git a/src/content/partials/ssl/add-client-certificate-rfc9440.mdx b/src/content/partials/ssl/add-client-certificate-rfc9440.mdx new file mode 100644 index 00000000000000..ad8c69601fb062 --- /dev/null +++ b/src/content/partials/ssl/add-client-certificate-rfc9440.mdx @@ -0,0 +1,155 @@ +--- +{} +--- + +import { Example } from "~/components"; + +## Add Client-Cert and Client-Cert-Chain headers (RFC 9440) + +[RFC 9440](https://datatracker.ietf.org/doc/html/rfc9440) defines the `Client-Cert` and `Client-Cert-Chain` HTTP header fields for passing client certificate information to origin servers. You can construct these headers using [request header modification rules](/rules/transform/request-header-modification/) with the following Rulesets fields: + +- [`cf.tls_client_auth.cert_rfc9440`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_rfc9440/) — The client leaf certificate encoded as a structured field byte sequence. +- [`cf.tls_client_auth.cert_chain_rfc9440`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_chain_rfc9440/) — The certificate chain (excluding the leaf certificate) encoded as a structured field list. + +Both fields contain values ready to use as RFC 9440 header values without any additional encoding. + +### Security considerations + +:::caution[Important] +Before constructing `Client-Cert` or `Client-Cert-Chain` headers, you must address the following security concerns. Failing to do so can expose your origin server to forged or unverified certificate data. +::: + +The `cert_rfc9440` and `cert_chain_rfc9440` fields are populated **regardless of the certificate validation result**. This means a client can present an invalid, expired, or self-signed certificate, and the fields will still contain the encoded certificate data. Always check the following fields before trusting the values: + +- [`cf.tls_client_auth.cert_verified`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_verified/) — Returns `true` when the client certificate is valid. +- [`cf.tls_client_auth.cert_revoked`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_revoked/) — Returns `true` when the client certificate has been revoked. + +A client can also include its own `Client-Cert` or `Client-Cert-Chain` headers on a request to inject arbitrary values. As described in the [RFC 9440 security considerations](https://datatracker.ietf.org/doc/html/rfc9440#name-security-considerations), you must unconditionally remove any existing `Client-Cert` and `Client-Cert-Chain` headers from incoming requests, regardless of certificate validity. This prevents a client from injecting forged certificate data that your origin would trust. + +The example rules below use two rules per header to handle this correctly: the first rule removes the header on **every** request, and the second rule sets it only when the certificate is valid. + +For certificate validation, it is recommended to use [Bring your own CA (BYOCA)](/ssl/client-certificates/byo-ca/), [Cloudflare Access](/cloudflare-one/), or [API Shield](/api-shield/security/mtls/) so that Cloudflare can validate the certificate status on your behalf. + +### Size limits + +The encoded leaf certificate is limited to 10 KiB and the encoded chain is limited to 16 KiB. If the encoded value exceeds the limit, the corresponding field contains an empty string. Use the following fields to check for this condition: + +- [`cf.tls_client_auth.cert_rfc9440_too_large`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_rfc9440_too_large/) — Returns `true` when the encoded certificate exceeds 10 KiB. +- [`cf.tls_client_auth.cert_chain_rfc9440_too_large`](/ruleset-engine/rules-language/fields/reference/cf.tls_client_auth.cert_chain_rfc9440_too_large/) — Returns `true` when the encoded chain exceeds 16 KiB. + +### Example Transform Rules + +You need to create the following request header modification rules. The **Remove** rules must be placed before the **Set dynamic** rules so that client-injected headers are stripped on every request before the validated values are set. + +#### Rule 1 — Remove Client-Cert header + +This rule unconditionally removes any `Client-Cert` header sent by the client. + + + +Text in **Expression Editor**: + +```txt +true +``` + +Selected operation under **Modify request header**: _Remove_ + +**Header name**: `Client-Cert` + + + +#### Rule 2 — Remove Client-Cert-Chain header + +This rule unconditionally removes any `Client-Cert-Chain` header sent by the client. + + + +Text in **Expression Editor**: + +```txt +true +``` + +Selected operation under **Modify request header**: _Remove_ + +**Header name**: `Client-Cert-Chain` + + + +#### Rule 3 — Set Client-Cert header + +This rule sets the `Client-Cert` header only when the client presented a valid, non-revoked certificate that is within the size limit. + + + +Text in **Expression Editor**: + +```txt +cf.tls_client_auth.cert_verified and not cf.tls_client_auth.cert_revoked and not cf.tls_client_auth.cert_rfc9440_too_large +``` + +Selected operation under **Modify request header**: _Set dynamic_ + +**Header name**: `Client-Cert` + +**Value**: `cf.tls_client_auth.cert_rfc9440` + + + +#### Rule 4 — Set Client-Cert-Chain header + +This rule sets the `Client-Cert-Chain` header only when the client presented a valid, non-revoked certificate and the chain is within the size limit. + + + +Text in **Expression Editor**: + +```txt +cf.tls_client_auth.cert_verified and not cf.tls_client_auth.cert_revoked and not cf.tls_client_auth.cert_chain_rfc9440_too_large +``` + +Selected operation under **Modify request header**: _Set dynamic_ + +**Header name**: `Client-Cert-Chain` + +**Value**: `cf.tls_client_auth.cert_chain_rfc9440` + + + +### Cloudflare Workers + +You can also construct RFC 9440 headers in a [Cloudflare Worker](/workers/) using the [`tlsClientAuth`](/workers/runtime-apis/request/#incomingrequestcfproperties) properties on the incoming request: + +```js +export default { + async fetch(request) { + const headers = new Headers(request.headers); + + // Always remove client-injected headers to prevent field injection + headers.delete("Client-Cert"); + headers.delete("Client-Cert-Chain"); + + const tlsAuth = request.cf?.tlsClientAuth; + + // Only set headers if the certificate is valid and not revoked + if (tlsAuth?.certVerified === "SUCCESS" && tlsAuth?.certRevoked !== "1") { + if (tlsAuth.certRFC9440 && !tlsAuth.certRFC9440TooLarge) { + headers.set("Client-Cert", tlsAuth.certRFC9440); + } + + if (tlsAuth.certChainRFC9440 && !tlsAuth.certChainRFC9440TooLarge) { + headers.set("Client-Cert-Chain", tlsAuth.certChainRFC9440); + } + } + + return fetch(request.url, { + method: request.method, + headers, + body: request.body, + }); + }, +}; +``` + +The `headers.delete()` calls run unconditionally so that client-injected `Client-Cert` and `Client-Cert-Chain` headers are always stripped, even when no valid certificate was presented. diff --git a/src/content/partials/ssl/forward-client-certificate.mdx b/src/content/partials/ssl/forward-client-certificate.mdx index b366799d7eb4cb..8a8bef45231c4b 100644 --- a/src/content/partials/ssl/forward-client-certificate.mdx +++ b/src/content/partials/ssl/forward-client-certificate.mdx @@ -1,11 +1,10 @@ --- {} - --- import { APIRequest } from "~/components"; -## Forward a client certificate +## Forward a client certificate (legacy) In addition to enforcing mTLS authentication for your host, you can also forward a client certificate to your origin server as an HTTP header. This setup is often helpful for server logging. @@ -20,26 +19,30 @@ This process is only available on accounts with [Cloudflare Access](/cloudflare- The most common approach to forwarding a certificate is to use the Cloudflare API to [update an mTLS certificate's hostname settings](/api/resources/zero_trust/subresources/access/subresources/certificates/subresources/settings/methods/update/). ", - "china_network": false, - "client_certificate_forwarding": true - } - ] + path="/zones/{zone_id}/access/certificates/settings" + method="PUT" + json={{ + settings: [ + { + hostname: "", + china_network: false, + client_certificate_forwarding: true, + }, + ], }} code={{ - mark: [10] + mark: [10], }} /> Once `client_certificate_forwarding` is set to `true`, every request within an mTLS connection will now include the following headers: -* `Cf-Client-Cert-Der-Base64` -* `Cf-Client-Cert-Sha256` +- `Cf-Client-Cert-Der-Base64` +- `Cf-Client-Cert-Sha256` + +:::note +The `Cf-Client-Cert-Der-Base64` and `Cf-Client-Cert-Sha256` headers are a Cloudflare-proprietary mechanism. For a standardized approach, use [RFC 9440 `Client-Cert` and `Client-Cert-Chain` headers](/ssl/client-certificates/forward-a-client-certificate/#add-client-cert-and-client-cert-chain-headers-rfc-9440). +::: ### Managed Transforms @@ -51,14 +54,14 @@ Additionally, Workers can provide details around the [client certificate](/worke ```js const tlsHeaders = { - 'X-CERT-ISSUER-DN': request.cf.tlsClientAuth.certIssuerDN, - 'X-CERT-SUBJECT-DN': request.cf.tlsClientAuth.certSubjectDN, - 'X-CERT-ISSUER-DN-L': request.cf.tlsClientAuth.certIssuerDNLegacy, - 'X-CERT-SUBJECT-DN-L': request.cf.tlsClientAuth.certSubjectDNLegacy, - 'X-CERT-SERIAL': request.cf.tlsClientAuth.certSerial, - 'X-CERT-FINGER': request.cf.tlsClientAuth.certFingerprintSHA1, - 'X-CERT-VERIFY': request.cf.tlsClientAuth.certVerify, - 'X-CERT-NOTBE': request.cf.tlsClientAuth.certNotBefore, - 'X-CERT-NOTAF': request.cf.tlsClientAuth.certNotAfter + "X-CERT-ISSUER-DN": request.cf.tlsClientAuth.certIssuerDN, + "X-CERT-SUBJECT-DN": request.cf.tlsClientAuth.certSubjectDN, + "X-CERT-ISSUER-DN-L": request.cf.tlsClientAuth.certIssuerDNLegacy, + "X-CERT-SUBJECT-DN-L": request.cf.tlsClientAuth.certSubjectDNLegacy, + "X-CERT-SERIAL": request.cf.tlsClientAuth.certSerial, + "X-CERT-FINGER": request.cf.tlsClientAuth.certFingerprintSHA1, + "X-CERT-VERIFY": request.cf.tlsClientAuth.certVerify, + "X-CERT-NOTBE": request.cf.tlsClientAuth.certNotBefore, + "X-CERT-NOTAF": request.cf.tlsClientAuth.certNotAfter, }; ```