linkend="guc-authentication-timeout"/>).
Additionally, your provider may not provide introspection endpoints for
use by external resource servers.
</para>
<para>
Offline validation is much more involved, typically requiring a validator
to maintain a list of trusted signing keys for a provider and then
check the token's cryptographic signature along with its contents.
Implementations must follow the provider's instructions to the letter,
including any verification of issuer ("where is this token from?"),
audience ("who is this token for?"), and validity period ("when can this
token be used?"). Since there is no communication between the module and
the provider, tokens cannot be centrally revoked using this method;
offline validator implementations may wish to place restrictions on the
maximum length of a token's validity period.
</para>
<para>
If the token cannot be validated, the module should immediately fail.
Further authentication/authorization is pointless if the bearer token
wasn't issued by a trusted party.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Authorize the Client</term>
<listitem>
<para>
Next the validator must ensure that the end user has given the client
permission to access the server on their behalf. This generally involves
checking the scopes that have been assigned to the token, to make sure
that they cover database access for the current HBA parameters.
</para>
<para>
The purpose of this step is to prevent an OAuth client from obtaining a
token under false pretenses. If the validator requires all tokens to
carry scopes that cover database access, the provider should then loudly
prompt the user to grant that access during the flow. This gives them the
opportunity to reject the request if the client isn't supposed to be
using their credentials to connect to databases.
</para>
<para>
While it is possible to establish client authorization without explicit
scopes by using out-of-band knowledge of the deployed architecture, doing
so removes the user from the loop, which prevents them from catching
deployment mistakes and allows any such mistakes to be exploited
silently. Access to the database must be tightly restricted to only
trusted clients
<footnote>
<para>
That is, "trusted" in the sense that the OAuth client and the
<productname>PostgreSQL</productname> server are controlled by the same
entity. Notably, the Device Authorization client flow supported by
libpq does not usually meet this bar, since it's designed for use by
public/untrusted clients.
</para>
</footnote>
if users are not prompted for additional scopes.
</para>
<para>
Even if authorization fails, a module may choose to continue to pull
authentication information from the token for use in auditing and
debugging.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Authenticate the End User</term>
<listitem>
<para>
Finally, the validator should determine a user identifier for the token,
either by asking the provider for this information or by extracting it
from the token itself, and return that identifier to the server (which
will then make a final authorization decision using the HBA
configuration). This identifier will be available within the session via
<link linkend="functions-info-session-table"><function>system_user</function></link>
and recorded in the server logs if <xref linkend="guc-log-connections"/>
is enabled.
</para>
<para>
Different providers may record a variety of different authentication
information