RFC 0 | TLS Flag - Request Client Auth | June 2025 |
Hoyland | Informational | [Page] |
Normally in TLS there is no way for the client to signal to the server that it
supports client authentication and will handle a CertificateRequest
gracefully. This document defines a TLS Flag that enables clients to provide
this hint.¶
This document is not an Internet Standards Track specification; it is published for informational purposes.¶
This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Not all documents approved by the IESG are candidates for any level of Internet Standard; see Section 2 of RFC 7841.¶
Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at https://www.rfc-editor.org/info/rfc0.¶
Copyright (c) 2025 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
This document specifies a TLS Flag [I-D.ietf-tls-tlsflags] that allows a client to prompt the server to request a client certificate during the handshake. Sometimes a server does not want to authenticate every client, but might wish to authenticate a subset of them. In TLS 1.3 this may be done with post-handshake authentication, however this adds an extra round trip, and requires negotiation at the application layer.¶
The behaviour specified in [RFC8446] for a client that receives a
CertificateRequest
that it cannot satisfy is to send an empty Certificate
message followed by a Finished
message. However in practice many clients
simply terminate the connection in anticipation of a "certificate_required"
alert.¶
This behaviour makes it difficult for servers to send CertificateRequest
messages in the wild. A client sending the request_client_auth
flag in the
ClientHello
allows the server to request authentication during the initial
handshake only when it receives a hint the client will handle the request
without terminating the connection, and, if unable to authenticate, by sending
an empty Certificate
message, per [RFC8446], Section 4.4.2.¶
This mechanism is primarily intended to allow servers to cryptographically authenticate web crawlers and other trusted sources of automated traffic without prompting human users to present a certificate.¶
The traffic generated by these sources represents a significant and ever increasing fraction of the overall traffic to a given web server. Many web servers handle this traffic differently than they handle traffic from web browsers operated by human users. On the one hand, human users are much more latency sensitive than web crawlers. On the other hand, it may be prudent to treat requests from an unknown client with more scrutiny than requests from a well-known web-crawler whose behaviour is relatively predictable.¶
It is therefore common for web servers to attempt to identify trusted sources of traffic so that the server can distinguish between them, as well as differentiate them from human users. This dynamic creates an incentive for attackers to impersonate trusted sources of automated traffic to the server: to confer on themselves whatever accommodations are conferred on trusted sources. Unfortunately, many of the features used for self-identification are easily spoofed [I-D.draft-meunier-web-bot-auth-architecture].¶
Reaching the server normally requires first establishing a TLS [RFC8446] connection with it. Authentication of the TLS client is sufficient to thwart impersonation attacks, and while there are other approaches to solving this problem (see Appendix A.1), authentication at the TLS layer has several desirable features for this use case, both from a security and operational perspective.¶
The mechanism specified in this document may be used for other purposes, but doing so may entail security, privacy, or operational considerations that are relevant to these use cases but are not directly addressed here.¶
In particular, the request_client_auth
flag is not intended to be used by web
browsers or other clients operated directly by human users. Clients that set
this flag should only do so when a client certificate is directly available to
them, and must not prompt the user or take actions that would prompt the user
for example trying to read certificates from off-board devices such as smart
cards.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
The request_client_auth
flag is sent by the client in the ClientHello
message, and, if accepted by the server, acknowledged in the server's
CertificateRequest
message. A server that receives this flag and wishes to
accept the extension MUST send a CertificateRequest
message with the TLS
Flags extension, and with the request_client_auth
flag set. This informs the
client that the reason for the CertificateRequest
was because of the
request_client_auth
flag and not due to some other policy. This allows
clients to select certificates based on whether the server accepted the flag or
not.¶
The server MAY send a CertificateRequest
message without the
request_client_auth
flag set if it wishes to negotiate client authentication
for another reason. This could occur if, for example, the server is configured
to always request a client certificate.¶
The client sending this flag MUST send a Certificate
message if it receives a
CertificateRequest
with the request_client_auth
flag set, even if said
Certificate
message is empty, and SHOULD NOT preemptively terminate the
connection anticipating a "certificate_required" alert. Appropriate cases where
a client would preemptively terminate the connection include where the
CertificateRequest
includes a certificate_authorities
extension or
signature_algorithms
extension that the client cannot satisfy.¶
Clients that set this flag SHOULD only do so when a client certificate is directly available to them, and MUST NOT prompt the user or take actions that would prompt the user to provide a certificate.¶
A server MUST NOT set the request_client_auth
flag in the
CertificateRequest
unless it received the flag in the ClientHello
. A client
receiving the request_client_auth
flag that did not set it in the
ClientHello
MUST generate a fatal illegal_parameter
alert.¶
A client that receives this flag in any message other than CertificateRequest
MUST terminate the connection with a fatal illegal_parameter
alert. Similarly
a server that receives this flag in any message other than ClientHello
MUST
terminate the connection with a fatal illegal_parameter
alert.¶
TLS client authentication is bound to a particular TLS session. This means that a malicious server cannot manipulate a client in such a way that they can impersonate said client to any other server. This is due to the matching sessions property of TLS [DFGS21].¶
This differs sharply from e.g. HTTP Signatures for Web Bot Authentication (HSWBA) [I-D.draft-meunier-web-bot-auth-architecture], where the receiving server can relay a signature header to another server. In HSWBA this is intentional, as it enables the use of proxies.¶
This is because they authenticate different things. TLS client authentication identifies the actor you are talking to directly, whereas HSWBA identifies the actor that triggered some request, but not necessarily the actor you are in direct contact with.¶
We describe the difference between these two properties as "principal
authentication" and "agent authentication". Principals are the initiators of a
particular sequence of actions. It is expected for their authentication
information to be proxied from agent to agent as the relevant actions play out.
For example a crawler might request a webpage from a CDN, and the CDN may relay
the crawler's authentication, in the form of a Signature
header, to the
origin server. Agents, on the other hand, are the immediate participants in a
protocol. Each agent in a chain authenticates itself only to its direct peers,
i.e. those with whom it establishes a TLS connection.¶
The upside of agent authentication is that it is session-matching, i.e. it cannot be replayed. However that authentication cannot be passed on. The upside of principal authentication is that a single authority (the principal) can create a signature, and even if there is a long chain of proxies, each acting as an independent agent, the signature can be passed from one agent to another, and each agent can verify it independently. However, it suffers from issues with replays, see Appendix A.1.1.¶
In some cases it might be desirable to have both types of authentication, and in others only one. TLS client authentication provides agent authentication, the client leaf certificate acting to authenticate the agent, and HSWBA provide principal authentication, the signature authenticating the principal. It is possible for both protocols to be set up to provide the other as well, although this requires special deployment considerations. For example, the TLS Client can be issued with a certificate chain whose leaf provides authentication of the client, and whose CA provides authentication of the principal. Similarly HSWBA can provide agent authentication by including a binding from the exporter key interface in the signature. This is very similar to the techniques used in Token Binding [RFC8473], although Token Binding is only defined for TLS 1.2.¶
On its own, this flag should have no effect on the security of TLS, as the
server may always send a CertificateRequest
message during the handshake.
This flag merely provides a hint that the client will handle the request
gracefully. Because the server acknowledges the flag in the
CertificateRequest
the client can always be sure whether a
CertificateRequest
was triggered by request_client_auth
or not.¶
However, the use case for which the flag is enabled may entail significant changes to how the client selects a certificate and what trust anchors the server uses to validate it. The use case may also impact how the server handles application data transmitted over the established connection.¶
In the case of identifying web crawlers (Section 1), a web server would largely handle traffic from a web crawler as if it were any unauthenticated client. If for instance the server already requests a certificate to grant certain clients access to some resource, the server must take care to ensure this access is not also granted to the web crawler.¶
A server that uses one set of trust anchors to verify clients that send
req_client_auth
and another set of trust anchors to verify other traffic must
take care to ensure that the appropriate trust anchors are selected in each
case, otherwise it might be possible for a client to incorrectly gain access to
resources it should not be able to reach. If this is a risk in a given
deployment a potential mitigation is to ensure that the set of certificates
that chain to the bots trust anchors and those that chain to other sets of
trust anchors are disjoint.¶
This document requests IANA to add an entry to the TLS Flags registry in the TLS namespace with the following values:¶
HTTP Signatures for Web Bot Authentication [I-D.draft-meunier-web-bot-auth-architecture] describes a mechanism for implementing bearer tokens at the HTTP layer that authenticate requests. This mechanism suffers from a number of drawbacks, notably that a new signature must be created and verified for every request (rather than one per connection), and second that, because the tokens are not bound to the underlying TLS connection they can be stolen and replayed. This is especially problematic in the multi-CDN ("Content Distribution Network") use case. If a bot creates a token for a realm that is provided by more than one CDN then the CDN that receives that token can use it to attack any of the other CDNs. This means that all CDNs are required to trust each other.¶
Concealed Authentication [RFC9729] allows a client to attach a header at the
HTTP layer that cryptographically binds a public key to the underlying TLS
connection. This gives us a similar authentication property to using
request_client_auth
, and is also client initiated. This solution is
applicable in some contexts, but may be difficult to implement.¶
The way many HTTP libraries work is that they dispatch requests to a connection pool. Once the request arrives at the pool it is sent on a chosen connection driven by internal logic. This, unfortunately, makes it difficult to know which connection a request will be sent on, and thus to produce the appropriate signature.¶
It is possible to avoid this issue, for example by not using connection pooling, or by modifying the implementation to add the header on the first request of each connection. Where modifying the implementation is not possible various ad-hoc solutions can be used such as sending a special "pre-request" on each connection that's added to a pool. However these solutions tend to be bespoke per library and bring a number of their own issues (e.g. handling servers that terminate connections after a single request, or handling resumption).¶
Post-handshake authentication is part of the core TLS 1.3 RFC, although it is not widely supported. Its use incurs an extra round-trip, and would need negotiation at the application layer. This just trades one negotiation for another, whilst making the protocol more expensive to run. Further there are some reservations about its security guarantees [CHHSV17], Section 5.2.¶
One proposal is for the client to send new ALPN extensions, e.g. h2+bot
. This
is functionally equivalent to this draft, but with a less efficient encoding.
ALPN negotiation consists of a client sending a list of protocols it is willing
to speak over the TLS connection, and the server selecting exactly one.
Doubling the number of ALPN entries to include h2+bot, h2
and then having the
server select one by returning h2+bot
and a CertificateRequest
gives
exactly the same behaviours to the server receiving a TLS Flag, and echoing it.
As a side note, it is also an abuse of the ALPN mechanism, as h2
and h2+bot
are indistinguishable at the application layer, the difference is in the TLS
handshake. This proposal also has the downside of the edge case where the
server selecting h2+bot
but not sending a CertificateRequest
.¶
Exported Authenticators [RFC9261] allow clients to provide certificates at the application layer once the connection is established. A limitation of this mechanism is that it has to be triggered by the server, however an update to the mechanism to allow the client to send the certificate could also be used to solve this mechanism. This would require modifications to both the standard and the implementation.¶
TODO acknowledge.¶