fake server between the real
server and client from passing through the server's random value
and successfully authenticating.
</para>
<para>
<acronym>SCRAM</acronym> with channel binding prevents such
man-in-the-middle attacks by mixing the signature of the server's
certificate into the transmitted password hash. While a fake server can
retransmit the real server's certificate, it doesn't have access to the
private key matching that certificate, and therefore cannot prove it is
the owner, causing SSL connection failure.
</para>
<procedure>
<title>Example</title>
<step id="scram-begin">
<para>
The server sends an AuthenticationSASL message. It includes a list of
SASL authentication mechanisms that the server can accept.
This will be <literal>SCRAM-SHA-256-PLUS</literal>
and <literal>SCRAM-SHA-256</literal> if the server is built with SSL
support, or else just the latter.
</para>
</step>
<step id="scram-client-first">
<para>
The client responds by sending a SASLInitialResponse message, which
indicates the chosen mechanism, <literal>SCRAM-SHA-256</literal> or
<literal>SCRAM-SHA-256-PLUS</literal>. (A client is free to choose either
mechanism, but for better security it should choose the channel-binding
variant if it can support it.) In the Initial Client response field, the
message contains the SCRAM <structname>client-first-message</structname>.
The <structname>client-first-message</structname> also contains the channel
binding type chosen by the client.
</para>
</step>
<step id="scram-server-first">
<para>
Server sends an AuthenticationSASLContinue message, with a SCRAM
<structname>server-first-message</structname> as the content.
</para>
</step>
<step id="scram-client-final">
<para>
Client sends a SASLResponse message, with SCRAM
<structname>client-final-message</structname> as the content.
</para>
</step>
<step id="scram-server-final">
<para>
Server sends an AuthenticationSASLFinal message, with the SCRAM
<structname>server-final-message</structname>, followed immediately by
an AuthenticationOk message.
</para>
</step>
</procedure>
</sect2>
<sect2 id="sasl-oauthbearer">
<title>OAUTHBEARER Authentication</title>
<para>
<literal>OAUTHBEARER</literal> is a token-based mechanism for federated
authentication. It is described in detail in
<ulink url="https://datatracker.ietf.org/doc/html/rfc7628">RFC 7628</ulink>.
</para>
<para>
A typical exchange differs depending on whether or not the client already
has a bearer token cached for the current user. If it does not, the exchange
will take place over two connections: the first "discovery" connection to
obtain OAuth metadata from the server, and the second connection to send
the token after the client has obtained it. (libpq does not currently
implement a caching method as part of its builtin flow, so it uses the
two-connection exchange.)
</para>
<para>
This mechanism is client-initiated, like SCRAM. The client initial response
consists of the standard "GS2" header used by SCRAM, followed by a list of
<literal>key=value</literal> pairs. The only key currently supported by
the server is <literal>auth</literal>, which contains the bearer token.
<literal>OAUTHBEARER</literal> additionally specifies three optional
components of the client initial response (the <literal>authzid</literal> of
the GS2 header, and the <structfield>host</structfield> and
<structfield>port</structfield> keys) which are currently ignored by the
server.
</para>
<para>
<literal>OAUTHBEARER</literal> does not support channel binding, and there
is no "OAUTHBEARER-PLUS" mechanism. This mechanism does not make use of
server data during a