On this page
01 What mTLS proves between an edge and an origin
mTLS, mutual TLS, is the TLS handshake with client certificate authentication turned on. In the common web case only the server proves itself and accepts anyone. Between a CDN or load balancer and the origin behind it that asymmetry is a hole: the origin's address leaks through DNS history, certificate transparency logs and misconfigured headers, and once known, anyone can connect to it directly, bypassing whatever the edge enforces.
Origin authentication with mTLS closes that hole: the origin demands a certificate from every client and accepts only those issued by a CA it trusts for that purpose. The edge holds one; a stranger does not. What it proves is precise and limited: the party at the other end of this TCP connection holds the private key for a certificate this CA issued. It says nothing about the HTTP inside, and the Provenance on the Wire hub keeps the two questions, who is on the wire and whether the bytes are intact, deliberately separate.
02 How the TLS 1.3 handshake proves both sides
RFC 8446 describes the exchange. The client opens with ClientHello; the server replies with ServerHello and, from that point, every handshake message is encrypted under keys derived from the key exchange. The server sends its own Certificate and CertificateVerify and, when it wants client authentication, a CertificateRequest (Section 4.3.2) before them, which can list acceptable CA names and signature algorithms.
The client answers, after the server's Finished, with its own Certificate message (Section 4.4.2) and a CertificateVerify (Section 4.4.3): a signature, made with the private key matching the certificate, over a transcript hash of the handshake so far. That signature proves possession; a copied certificate without the key cannot produce it. Because these messages are inside the encrypted part of the handshake, a passive observer never sees the client certificate, unlike TLS 1.2 where it went in clear.
Section 4.4.2.4 gives the server's options on a bad or absent certificate: on an empty Certificate message it may continue unauthenticated or abort with certificate_required; on a chain that does not verify it may treat the client as unauthenticated or abort. For an origin the only correct choice is to abort. TLS 1.3 also permits post-handshake authentication (Section 4.6.2) on an open connection if the client offered post_handshake_auth; edge-to-origin deployments authenticate at the handshake instead.
03 What a private CA for mTLS looks like
Client certificates for this path should never come from a public CA. A public CA issues to anyone who proves control of a name, so the origin would accept any publicly issued certificate unless you pin further. Run a private CA whose only job is to issue client certificates for this path, and have the origin trust that CA and nothing else for client authentication.
The structure follows RFC 5280. A root key kept offline signs one or two intermediate CAs; the intermediates issue short-lived leaf certificates to edge nodes. Each leaf carries a Subject Alternative Name that identifies the node or the edge service, an extendedKeyUsage of clientAuth, and a validity of days to a few weeks rather than the year or more typical of server certificates. The origin trusts the root; the edge presents leaf plus intermediate so the origin can build the chain. Short validity replaces CRL or OCSP checks on the origin, which would add a network dependency to every handshake.
04 Configuration shape on the proxy and the origin
The shape is the same on any reverse proxy or web server; only the directive names change. The origin needs its own server certificate, a CA bundle to verify clients against, and a setting that makes client verification mandatory. The edge needs the client certificate, its key, and the CA it expects the origin to present. The transcript is illustrative, not any product's syntax.
# origin side tls_certificate /etc/tls/origin.crt tls_key /etc/tls/origin.key client_ca_bundle /etc/tls/edge-ca-root.pem client_verify required client_verify_depth 2 # edge side, per upstream upstream_tls_sni origin.internal.example upstream_client_cert /etc/tls/edge-node-17.crt upstream_client_key /etc/tls/edge-node-17.key upstream_ca_bundle /etc/tls/origin-ca.pem
Create the private CA
Generate a root key offline and an intermediate key online; sign the intermediate with the root. Publish only the root certificate to origins as their trust anchor.
Issue an edge client certificate
Create a key on each edge node or edge service, issue a leaf from the intermediate with clientAuth key usage and a short validity, and install leaf plus intermediate on the edge.
Enable required client verification on the origin
Point the origin at the root, set verification to required with a depth that admits the intermediate, and restart. From this moment unauthenticated connections are refused at the handshake.
Configure the edge upstream
Attach the client certificate and key to the upstream definition, set the SNI to the origin's certificate name, and verify the origin's chain against the CA you expect.
Test both directions
Connect from the edge and confirm a 200. Connect from a host with no certificate and confirm certificate_required; connect with an expired one and confirm certificate_expired.
Automate rotation
Reissue leaves well inside their validity and deploy while the old one is still valid; during a CA roll trust both roots on the origin until the last old leaf has expired.
05 Worked example: a two-node edge in front of one origin
Take two edge nodes in front of one origin in a balancer and real server pool design. The private root is created once and kept offline. An intermediate, edge-ca-int-1, issues edge-node-a and edge-node-b leaves, each valid fourteen days with reissue at day seven. The origin trusts the root, requires client verification, and logs the client certificate's subject.
On day seven the reissue job produces new leaves and the edge reloads; both old and new are valid, so no handshake fails, and on day fourteen the old leaves expire unused. A direct connection to the origin's public address from anywhere else now fails with certificate_required, and the origin log shows only the TLS alert, since no HTTP request was completed. The origin is, in effect, unreachable by anyone who is not the edge. A layer 4 balancer that passes TLS through cannot take part, because it never holds a certificate; the distinction is drawn in where a layer 7 device terminates TLS.
06 mTLS versus the alternatives for origin authentication
| Method | What it proves | Where it breaks | Operational cost |
|---|---|---|---|
| mTLS (client certificates) | Peer holds a key issued by your CA; proof is per connection and cannot be replayed | Expired certs, missing intermediates, clock skew | Running a CA, rotation automation |
| IP allowlist at the origin | Packet arrived from an address in the list | Edge address ranges change; shared ranges admit neighbours; spoofing on some paths | A list to maintain; no crypto |
| Shared secret header | Sender knew a string | Any log, proxy or leak reveals it; replayable forever until rotated | Trivial to set up, hard to rotate safely |
| Signed requests (RFC 9421) | Sender held the signing key and the covered fields are intact | Proxies that rewrite covered fields | Per-request signing and verification |
07 Failure modes and how they present
- Expired client certificate. The origin sends
certificate_expiredand the edge logs an upstream TLS failure while the origin itself looks healthy. Short validity makes this the most common outage, which is why reissue must be automated and alarmed. - Missing intermediate. The edge presents only its leaf, the origin trusts only the root, and the chain cannot be built:
unknown_ca. Install the intermediate alongside the leaf on the client side; the sender supplies the chain, the receiver does not guess it. - SNI mismatch. The edge connects by address but sends a Server Name Indication that does not match the origin's certificate, or none at all; the origin selects a default certificate and the edge's verification of the server fails. Set the upstream SNI explicitly.
- Clock skew. A leaf valid from 09:00 presented at 08:58 by a slow clock is not yet valid. Keep every node on NTP and start validity a few minutes in the past.
- Certificate pinning gone stale. Pinning the origin's exact leaf on the edge, rather than trusting the CA, turns every origin certificate renewal into an outage. Pin the private CA, not the leaf.
None of these failures reaches the end user as anything but a 502 from the edge, which is why the edge must log the TLS alert name it received from the origin. For the complementary question of who the client at the edge is, rather than who the edge is to the origin, see the bot verification procedure.
Endpoint identity is one of four questions the network-layer provenance lane answers. The other three are covered by verifying a crawler before you trust its token, proving the bytes were not altered between edge and reader and proving the route that carried them was authentic.
08 Questions
What is the difference between TLS and mTLS?
In TLS only the server presents a certificate and proves possession of its key. In mTLS the server also sends a CertificateRequest and the client answers with its certificate and a CertificateVerify signature over the handshake, so both ends are authenticated before application data flows.
Does mTLS prove the content is unchanged?
It proves the connection is between two identified key holders and, like any TLS session, that bytes were not altered on that hop. It does not prove the content was correct before it entered the connection, or that an earlier hop did not change it. Content integrity needs digests or signatures on the payload.
Can I use certificates from a public CA for mTLS?
You can, but you should not for an edge-to-origin path. A public CA issues to anyone who controls a name, so the origin would accept any such certificate unless you also pin names. A private CA whose only clients are your edge nodes gives a clean trust boundary.
How often should client certificates rotate?
Days to a few weeks for automated edge nodes, with reissue at roughly half the validity so a missed run does not cause an outage. Short validity also removes the need for revocation checking on the origin, which would add a network dependency to every handshake.
What does certificate_required mean in the origin log?
The origin demanded a client certificate and the client sent an empty Certificate message. RFC 8446 lets a server continue unauthenticated or abort with this alert; an origin that requires mTLS aborts. It usually means a connection from something other than the edge, or an edge node whose certificate failed to load.
Is TLS 1.3 required for mTLS?
No, TLS 1.2 supports client certificates too, but TLS 1.3 encrypts the client certificate inside the handshake and removes weak cipher suites. NIST SP 800-52 Revision 2 sets TLS 1.2 as the minimum for government systems and requires TLS 1.3 support; build new origin paths on 1.3.
mTLS is the cheapest strong answer to who is on the other end of an origin connection, and the private CA behind it is a small amount of tooling that pays for itself the first time an origin address leaks. Once the edge is authenticated to the origin, the next question is whether the bytes it carries are intact, the subject of content integrity in transit.