however, the rules for emitting
log entries to the client are subtly different during the authentication
phase of the connection. Generally speaking, modules should log
verification problems at the <symbol>COMMERROR</symbol> level and return
normally, instead of using <symbol>ERROR</symbol>/<symbol>FATAL</symbol>
to unwind the stack, to avoid leaking information to unauthenticated
clients.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Interruptibility</term>
<listitem>
<para>
Modules must remain interruptible by signals so that the server can
correctly handle authentication timeouts and shutdown signals from
<application>pg_ctl</application>. For example, blocking calls on sockets
should generally be replaced with code that handles both socket events
and interrupts without races (see <function>WaitLatchOrSocket()</function>,
<function>WaitEventSetWait()</function>, et al), and long-running loops
should periodically call <function>CHECK_FOR_INTERRUPTS()</function>.
Failure to follow this guidance may result in unresponsive backend
sessions.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Testing</term>
<listitem>
<para>
The breadth of testing an OAuth system is well beyond the scope of this
documentation, but at minimum, negative testing should be considered
mandatory. It's trivial to design a module that lets authorized users in;
the whole point of the system is to keep unauthorized users out.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Documentation</term>
<listitem>
<para>
Validator implementations should document the contents and format of the
authenticated ID that is reported to the server for each end user, since
DBAs may need to use this information to construct pg_ident maps. (For
instance, is it an email address? an organizational ID number? a UUID?)
They should also document whether or not it is safe to use the module in
<symbol>delegate_ident_mapping=1</symbol> mode, and what additional
configuration is required in order to do so.
</para>
</listitem>
</varlistentry>
</variablelist>
</sect2>
<sect2 id="oauth-validator-design-usermap-delegation">
<title>Authorizing Users (Usermap Delegation)</title>
<para>
The standard deliverable of a validation module is the user identifier,
which the server will then compare to any configured
<link linkend="auth-username-maps"><filename>pg_ident.conf</filename>
mappings</link> and determine whether the end user is authorized to connect.
However, OAuth is itself an authorization framework, and tokens may carry
information about user privileges. For example, a token may be associated
with the organizational groups that a user belongs to, or list the roles
that a user may assume, and duplicating that knowledge into local usermaps
for every server may not be desirable.
</para>
<para>
To bypass username mapping entirely, and have the validator module assume
the additional responsibility of authorizing user connections, the HBA may
be configured with <xref linkend="auth-oauth-delegate-ident-mapping"/>.
The module may then use token scopes or an equivalent method to decide
whether the user is allowed to connect under their desired role. The user
identifier will still be recorded by the server, but it plays no part in
determining whether to continue the connection.
</para>
<para>
Using this scheme, authentication itself is optional. As long as the module
reports that the connection is authorized, login will continue even if there
is no recorded user identifier at all. This makes it possible to implement
anonymous or pseudonymous access to the database, where