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 successful authentication, so the
AuthenticationSASLFinal message is not used in the exchange.
</para>
<procedure>
<title>Example</title>
<step>
<para>
During the first exchange, the server sends an AuthenticationSASL message
with the <literal>OAUTHBEARER</literal> mechanism advertised.
</para>
</step>
<step>
<para>
The client responds by sending a SASLInitialResponse message which
indicates the <literal>OAUTHBEARER</literal> mechanism. Assuming the
client does not already have a valid bearer token for the current user,
the <structfield>auth</structfield> field is empty, indicating a discovery
connection.
</para>
</step>
<step>
<para>
Server sends an AuthenticationSASLContinue message containing an error
<literal>status</literal> alongside a well-known URI and scopes that the
client should use to conduct an OAuth flow.
</para>
</step>
<step>
<para>
Client sends a SASLResponse message containing the empty set (a single
<literal>0x01</literal> byte) to finish its half of the discovery
exchange.
</para>
</step>
<step>
<para>
Server sends an ErrorMessage to fail the first exchange.
</para>
<para>
At this point, the client conducts one of many possible OAuth flows to
obtain a bearer token, using any metadata that it has been configured with
in addition to that provided by the server. (This description is left
deliberately vague; <literal>OAUTHBEARER</literal> does not specify or
mandate any particular method for obtaining a token.)
</para>
<para>
Once it has a token, the client reconnects to the server for the final
exchange:
</para>
</step>
<step>
<para>
The server once again sends an AuthenticationSASL message with the
<literal>OAUTHBEARER</literal> mechanism advertised.
</para>
</step>
<step>
<para>
The client responds by sending a SASLInitialResponse message, but this
time the <structfield>auth</structfield> field in the message contains the
bearer token that was obtained during the client flow.
</para>
</step>
<step>
<para>
The server validates the token according to the instructions of the
token provider. If the client is authorized to connect, it sends an
AuthenticationOk message to end the SASL exchange.
</para>
</step>
</procedure>
</sect2>
</sect1>
<sect1 id="protocol-replication">
<title>Streaming Replication Protocol</title>
<para>
To initiate streaming replication, the frontend sends the
<literal>replication</literal> parameter in the startup message. A Boolean
value of <literal>true</literal> (or <literal>on</literal>,
<literal>yes</literal>, <literal>1</literal>) tells the backend to go into
physical replication walsender mode, wherein a small set of replication