Mutual TLS at a load balancer can look deceptively complete. HAProxy verifies a client certificate against a configured CA and accepts the TLS connection. The application behind the proxy may then receive an identity header or a certificate subject. The security result depends on what the proxy verified, what it forwarded, and whether the backend performs its own trust and authorization checks.
HAProxy's client certificate tutorial shows verify required and ca-file on the frontend bind line. That configuration requires a client certificate and validates it against the named CA. It does not automatically map every valid certificate to an application role. A certificate issued for one service or population can still be valid for the CA while being inappropriate for a specific route.
The review should start at the listener. Which CA bundle is loaded? Is it the issuing CA for this service or a broad enterprise root that also signs unrelated client certificates? Does the chain include intermediates? Is revocation checked, and what happens when the revocation source is unavailable? Does the listener reject a missing certificate before any HTTP processing occurs?
Separate termination from backend trust
If HAProxy forwards a header that contains the verified subject, the backend must treat that header as trusted only from the proxy. A direct client that can reach the backend and set the same header can otherwise impersonate a certificate user. Network policy should prevent direct access, and the backend should authenticate the proxy connection or verify a signed assertion when the network boundary is not sufficient.
When HAProxy re-encrypts to the backend, the backend connection has its own TLS identity. A server line with ssl verify required ca-file validates the server certificate against the configured CA. That check is separate from client verification at the frontend. Do not assume that verify required on one side configures both directions.
An application that needs to authorize a specific certificate should receive stable, verified attributes. Decide which subject or SAN field is the identity, how it is normalized, and which group or role it maps to. Avoid building authorization from a header that the client can supply. If the proxy passes the full certificate, validate its freshness and provenance before use. If it passes only a subject, protect that header and define the trust boundary explicitly.
Test the failure paths
A useful acceptance suite includes a valid client certificate for an allowed identity, a valid certificate for a disallowed identity, a certificate signed by the wrong CA, an expired certificate, a revoked certificate, and no certificate. Each case should reach a deterministic result at the listener or the application. The test should verify that a rejected connection does not leave a partially authenticated session or a permissive fallback route.
Test the CA bundle after a rotation. Reload the new intermediate and root material, then confirm that old and new client certificates behave as policy requires. A file that loads successfully is not evidence that it contains the intended chain. Inspect the certificate subject and issuer on a test connection and compare it with the expected values.
If the proxy is used for multiple applications, separate CA bundles or certificate profiles where the authorization populations differ. One shared client CA makes every valid certificate a candidate at every listener unless another layer restricts it. A common root is convenient for operations; it is not an application-level authorization decision.
Review the handoff as a contract
Document the listener, CA, certificate profile, forwarded identity, backend authentication, and application role mapping in one record. Assign an owner to each field. On a change to the CA or certificate template, update the record and run the failure tests. On a change to the backend, verify that it still requires the proxy trust boundary.
HAProxy can enforce a strong client-certificate gate. The gate is useful when its chain, revocation behavior, identity mapping, and backend handoff are all under review. A valid certificate should identify a peer; it should not by itself imply access to every route behind the proxy.