aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorJacob Champion <jchampion@postgresql.org>2025-05-01 09:14:30 -0700
committerJacob Champion <jchampion@postgresql.org>2025-05-01 09:14:30 -0700
commitb0635bfda0535a7fc36cd11d10eecec4e2a96330 (patch)
tree13a39de30ba014942dc006a023102a6d9bf2fa51 /doc
parenta3ef0b570c56f7bb15e4aa5caf0125fff92a557a (diff)
downloadpostgresql-b0635bfda0535a7fc36cd11d10eecec4e2a96330.tar.gz
postgresql-b0635bfda0535a7fc36cd11d10eecec4e2a96330.zip
oauth: Move the builtin flow into a separate module
The additional packaging footprint of the OAuth Curl dependency, as well as the existence of libcurl in the address space even if OAuth isn't ever used by a client, has raised some concerns. Split off this dependency into a separate loadable module called libpq-oauth. When configured using --with-libcurl, libpq.so searches for this new module via dlopen(). End users may choose not to install the libpq-oauth module, in which case the default flow is disabled. For static applications using libpq.a, the libpq-oauth staticlib is a mandatory link-time dependency for --with-libcurl builds. libpq.pc has been updated accordingly. The default flow relies on some libpq internals. Some of these can be safely duplicated (such as the SIGPIPE handlers), but others need to be shared between libpq and libpq-oauth for thread-safety. To avoid exporting these internals to all libpq clients forever, these dependencies are instead injected from the libpq side via an initialization function. This also lets libpq communicate the offsets of PGconn struct members to libpq-oauth, so that we can function without crashing if the module on the search path came from a different build of Postgres. (A minor-version upgrade could swap the libpq-oauth module out from under a long-running libpq client before it does its first load of the OAuth flow.) This ABI is considered "private". The module has no SONAME or version symlinks, and it's named libpq-oauth-<major>.so to avoid mixing and matching across Postgres versions. (Future improvements may promote this "OAuth flow plugin" to a first-class concept, at which point we would need a public API to replace this anyway.) Additionally, NLS support for error messages in b3f0be788a was incomplete, because the new error macros weren't being scanned by xgettext. Fix that now. Per request from Tom Lane and Bruce Momjian. Based on an initial patch by Daniel Gustafsson, who also contributed docs changes. The "bare" dlopen() concept came from Thomas Munro. Many people reviewed the design and implementation; thank you! Co-authored-by: Daniel Gustafsson <daniel@yesql.se> Reviewed-by: Andres Freund <andres@anarazel.de> Reviewed-by: Christoph Berg <myon@debian.org> Reviewed-by: Daniel Gustafsson <daniel@yesql.se> Reviewed-by: Jelte Fennema-Nio <postgres@jeltef.nl> Reviewed-by: Peter Eisentraut <peter@eisentraut.org> Reviewed-by: Wolfgang Walther <walther@technowledgy.de> Discussion: https://postgr.es/m/641687.1742360249%40sss.pgh.pa.us
Diffstat (limited to 'doc')
-rw-r--r--doc/src/sgml/installation.sgml8
-rw-r--r--doc/src/sgml/libpq.sgml30
2 files changed, 30 insertions, 8 deletions
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index e7ffb942bbd..60419312113 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -315,6 +315,14 @@
<listitem>
<para>
+ You need <productname>Curl</productname> to build an optional module
+ which implements the <link linkend="libpq-oauth">OAuth Device
+ Authorization flow</link> for client applications.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
You need <productname>LZ4</productname>, if you want to support
compression of data with that method; see
<xref linkend="guc-default-toast-compression"/> and
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 8cdd2997d43..695fe958c3e 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -10226,15 +10226,20 @@ void PQinitSSL(int do_ssl);
<title>OAuth Support</title>
<para>
- libpq implements support for the OAuth v2 Device Authorization client flow,
+ <application>libpq</application> implements support for the OAuth v2 Device Authorization client flow,
documented in
<ulink url="https://datatracker.ietf.org/doc/html/rfc8628">RFC 8628</ulink>,
- which it will attempt to use by default if the server
+ as an optional module. See the <link linkend="configure-option-with-libcurl">
+ installation documentation</link> for information on how to enable support
+ for Device Authorization as a builtin flow.
+ </para>
+ <para>
+ When support is enabled and the optional module installed, <application>libpq</application>
+ will use the builtin flow by default if the server
<link linkend="auth-oauth">requests a bearer token</link> during
authentication. This flow can be utilized even if the system running the
client application does not have a usable web browser, for example when
- running a client via <application>SSH</application>. Client applications may implement their own flows
- instead; see <xref linkend="libpq-oauth-authdata-hooks"/>.
+ running a client via <acronym>SSH</acronym>.
</para>
<para>
The builtin flow will, by default, print a URL to visit and a user code to
@@ -10252,6 +10257,11 @@ Visit https://example.com/device and enter the code: ABCD-EFGH
to untrusted third parties.
</para>
<para>
+ Client applications may implement their own flows to customize interaction
+ and integration with applications. See <xref linkend="libpq-oauth-authdata-hooks"/>
+ for more information on how add a custom flow to <application>libpq</application>.
+ </para>
+ <para>
For an OAuth client flow to be usable, the connection string must at minimum
contain <xref linkend="libpq-connect-oauth-issuer"/> and
<xref linkend="libpq-connect-oauth-client-id"/>. (These settings are
@@ -10366,7 +10376,9 @@ typedef struct _PGpromptOAuthDevice
</synopsis>
</para>
<para>
- The OAuth Device Authorization flow included in <application>libpq</application>
+ The OAuth Device Authorization flow which
+ <link linkend="configure-option-with-libcurl">can be included</link>
+ in <application>libpq</application>
requires the end user to visit a URL with a browser, then enter a code
which permits <application>libpq</application> to connect to the server
on their behalf. The default prompt simply prints the
@@ -10378,7 +10390,8 @@ typedef struct _PGpromptOAuthDevice
This callback is only invoked during the builtin device
authorization flow. If the application installs a
<link linkend="libpq-oauth-authdata-oauth-bearer-token">custom OAuth
- flow</link>, this authdata type will not be used.
+ flow</link>, or <application>libpq</application> was not built with
+ support for the builtin flow, this authdata type will not be used.
</para>
<para>
If a non-NULL <structfield>verification_uri_complete</structfield> is
@@ -10400,8 +10413,9 @@ typedef struct _PGpromptOAuthDevice
</term>
<listitem>
<para>
- Replaces the entire OAuth flow with a custom implementation. The hook
- should either directly return a Bearer token for the current
+ Adds a custom implementation of a flow, replacing the builtin flow if
+ it is <link linkend="configure-option-with-libcurl">installed</link>.
+ The hook should either directly return a Bearer token for the current
user/issuer/scope combination, if one is available without blocking, or
else set up an asynchronous callback to retrieve one.
</para>