Is it possible to have route specific mTLS authentication? For example route service-1/* would need a client certificate but route api/* would not.
4. Error messages and/or full log output:
5. What I already tried:
To define new site block with https://our.organization.fi/service-1* requiring mTLS for all routes inside that block. Instead requiring certificate for routes service-1/* Caddy requires now certificate for all routes defined in any site block.
Unfortunately, that’s not possible right now, because the TLS auth is performed when the TLS handshake happens, which is before Caddy has decrypted the bytes and can look at the HTTP request.
You’d have to at least request a client cert at the TLS handshake, then enforce the certificate later in your HTTP routes.
Since not all TLS connections require a client cert in your case, you’d want to set a looser mode of client auth such as request or verify_if_given instead of require_and_verify.
Then you’d probably want to use the {http.request.tls.client.*} placeholders here:
along with a matcher, maybe the expression matcher, to enforce the client cert at the HTTP routing layer.
If this works, is common enough, and cumbersome at the same time, maybe a first-class matcher for TLS connections is warranted.
Thanks @matt for the clarification! It sounds indeed a bit cumbersome to configure. Probably we will also look into alternative ways to verify that the sender is whom it says it is, e.g. with private key signed JWT tokens.
Just a silly question, is it possible to include the client certificates when reverse proxying the request? By this, the certificate could be verified in the service behind Caddy.
Yes, you can pass it through as a request header with header_up and using one of those request placeholders.
You may need to wait for the next release or build from source if you take this approach though, since a new header-safe placeholder was just recently added to the codebase: