Re: [oauth] Stabilize the libpq-oauth ABI (and allow alternative implementations?)

From: Jacob Champion <jacob(dot)champion(at)enterprisedb(dot)com>
To: PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>
Cc: Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com>, Zsolt Parragi <zsolt(dot)parragi(at)percona(dot)com>
Subject: Re: [oauth] Stabilize the libpq-oauth ABI (and allow alternative implementations?)
Date: 2026-02-24 22:51:16
Message-ID: CAOYmi+mEU_q9sr1PMmE-4rLwFN=OjyndDwFZvpsMU3RNJLrM9g@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Tue, Dec 16, 2025 at 9:40 AM Jacob Champion
<jacob(dot)champion(at)enterprisedb(dot)com> wrote:
> Open questions remain:
> 1) 0004: Any objections to putting PQExpBuffer into libpq-fe.h?

Tom sounded lukewarm to this on the Discord, so I looked into
replacing the new usage with a simple char*.

That actually exposed a bug: appending error data during cleanup
doesn't help us at all, because we've already stopped using the error
buffer. In fact my whole idea of adding things to conn->errorMessage
during a teardown operation has been nearly useless from the
beginning. Elsewhere in libpq, we handle cases like these (which
should ideally just not happen) by printing warnings to stderr, so
v3-0001 does that instead.

Besides exposing a bug, switching to char* means anyone who's not
programming in C and already has code that handles pointer ownership
across the boundary can continue to make use of that, instead of
adapting to a completely new API for this one particular use case. We
already have the cleanup-callback requirement for the token anyway;
it's fine.

> 2) 0004: Thoughts on the v2 inheritance struct style as opposed to
> relying on implementations to double-check the struct length?

Still feels half-dozen or the other to me, so I'm planning to move
ahead with the inheritance model. I'll look into
VALGRIND_MAKE_MEM_NOACCESS (and/or other ways to catch people
scribbling where they shouldn't) for v4.

> 3) 0005: Should I add the thread lock to an init() API, or expose a
> new PQgetThreadLock() that other code can use?

v3-0002 implements PQgetThreadLock(). The conversation with Nico
Williams at [1] cemented this for me; it's entirely possible that
implementations will need the lock at other times besides
initialization, say if they're mixing OAuth with Kerberos. Adding a
way to retrieve it doesn't actually expose new functionality --
applications could always get at our internal implementation by
calling PQregisterThreadLock(NULL) -- but libraries can't use that API
safely.

Also, clients can probably make use of some of the newer ways of doing
this kind of initialization (pthread_once, etc.) that weren't in wide
use back when the init-function design showed up. We may not ever
actually need a separate init function, and if I'm wrong we can always
add one.

I think I'll put this in its own top-level thread for comment.

> (In other words, a plugin architecture causes the compile-time
> and run-time dependency arrows to point in opposite directions, so
> plugins won't be able to rely on the LIBPQ_HAS_* macros to determine
> what APIs are available to them.)
>
> (TODO: Are there implications for our use of RTLD_NOW at dlopen() time?

To answer my own question, yes: any future libpq-oauth plugin that
needs PG20+ APIs will have to lazy-load them (weak symbol
declarations, etc.) or else accept that long-running applications may
fail OAuth connections until they restart.

A more general plugin system would need to solve this. For example, we
could load RTLD_LAZY, check for a minimum libpq version declared by
the plugin, and then either upgrade the bindings with RTLD_NOW, or
dlclose() and bail. But I don't think I need to be solving a
nonexistent problem now.

--Jacob

[1] https://postgr.es/m/aSSp03wmNMngi/Oe%40ubby

Attachment Content-Type Size
v3-0001-oauth-Report-cleanup-errors-as-warnings-on-stderr.patch application/x-patch 2.2 KB
v3-0002-libpq-Add-PQgetThreadLock-to-mirror-PQregisterThr.patch application/x-patch 3.0 KB
v3-0003-libpq-Introduce-PQAUTHDATA_OAUTH_BEARER_TOKEN_V2.patch application/x-patch 24.5 KB
v3-0004-libpq-oauth-Use-the-PGoauthBearerRequestV2-API.patch application/x-patch 43.8 KB
v3-0005-libpq-oauth-Never-link-against-libpq-s-encoding-f.patch application/x-patch 3.2 KB
v3-0006-WIP-Introduce-third-party-OAuth-flow-plugins.patch application/x-patch 38.3 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Jacob Champion 2026-02-24 22:59:04 Re: pgsql: libpq: Grease the protocol by default
Previous Message Andrew Dunstan 2026-02-24 22:49:32 Re: pgsql: libpq: Grease the protocol by default