Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vvjM9-00GOf6-1E for pgsql-hackers@arkaria.postgresql.org; Thu, 26 Feb 2026 21:57:13 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vvjM8-00FkA3-15 for pgsql-hackers@arkaria.postgresql.org; Thu, 26 Feb 2026 21:57:12 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vvjM7-00Fk9a-2u for pgsql-hackers@lists.postgresql.org; Thu, 26 Feb 2026 21:57:12 +0000 Received: from mail-qv1-xf32.google.com ([2607:f8b0:4864:20::f32]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1vvjM4-00000001N0j-0Svz for pgsql-hackers@postgresql.org; Thu, 26 Feb 2026 21:57:10 +0000 Received: by mail-qv1-xf32.google.com with SMTP id 6a1803df08f44-896f5af3d8aso22345806d6.1 for ; Thu, 26 Feb 2026 13:57:09 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1772143028; cv=none; d=google.com; s=arc-20240605; b=lum2CHEiErd1fd6C4pNj20Bydro3LziIXhSLiag36F8qlWDRmLzgbaGLoyLVLPNeP4 z1xSMEj8PaMJJPZoXmAo3odAjeXMFht6xeIQQvoEwjsPsMQTT9ZDhluJUc+seix4BxK1 GU5DFNuuGv/hIVpheT3B4LhQYuz6QM+HHxJt8SRy3LJhvpZFHZu2ONAstMpJK3E0wDt3 ukdHAQZMs/rjtLUiE6qxQtwE7+8QQTv9UrAKpWIAPxuvrSH4kt222lFId7WsLvwoOzkA 0PG175B7MhQFpQvcf/6GF6z9DiPTlt84bjmQ6qeS8a32hjKC4DPPybsPslvFAxM1i4Cn cpeQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=qd6byD9W/6qTwAdfkfxd0RXKj16DdJdFzVTxdWF1+iM=; fh=pfkmzW6GKlJ0l1fsmHrQ2YGNtR4HiNVrGovoMNulRlY=; b=QaK28XFbJg7ju/tM0pUHPpAD3RjH+j9Mac6uLOtCR8tWx5DKHZOAB8FWxPk61NV+5i BAtfipIcHWv29C3yFtq8OTuC/Gyv/2ZRMGA8uaaIjmr0+CLih2nB/C+JKp5kQX1PAIsO 25D/LURRJKdZ/uUw7CKx9RETzyqPKBLltkIXrh+6SGPk+R4WN9uz/sD1I0mYeYDhgpAF KVv0/ran1hNclaIn1C7tgYTl8oX6inY+FYtL21kOXqW3bB001uHLYy5gIAKyS2rWdLjz Q5uvOq6zm4QnkbBtzNaiqW84GZLE8nPDQxgGaPf4ZEHRzyYlDn5W/nJzLloXsRndRltZ quDw==; darn=postgresql.org ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; t=1772143028; x=1772747828; darn=postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=qd6byD9W/6qTwAdfkfxd0RXKj16DdJdFzVTxdWF1+iM=; b=ErWf5l159h/0vB2BfJ0mpuxt4OKiyyXL1IwBNy77XxfWyGNn/M7h8hM0eOI3pGlWOC Ypu2tqbrcLJQfJaC1M8FpcYtwhBb7iz1lVSZIg9VDUxLLTHxQvpeaQaN1toF50KgXSIK pfjM0hE8b3Qw68CFOPPEhWXmV5jPz5QeoI8muL4jIhg53zOQpijQxOd5Bnm0pRbjYNnu hcaSbK1+oT8/q1tfupCqg9gOKNKQ6BQKTNDkAUi2xHxWlgYxxxLz3YJ6V9pHSTW5PiO2 b14VL+o1ey2viaCx2gnQBbynwMLcvbzXRQrZnFRqOkyf3u1tG24fjxqHzZWnXhdqgpet 7z2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772143028; x=1772747828; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=qd6byD9W/6qTwAdfkfxd0RXKj16DdJdFzVTxdWF1+iM=; b=ln7BPU9l0QAHzMlVefu9ZVOT0NWCXiz7//eKOeoAyPS3ZBS1oT2iyN0h2LAxWelSk9 9Z4qLm97lDA6IAu7q/pO3bfsLUeSqJXmC/D4hCy/9z1cZgCExxiNM5Trt2vHrS7QNrl2 CmzMYjCXa1SuQ69ZEfYTEtV5tIzCeBzT1/Mtb8YbkiArGdxENNpS9WKeHWXgbAZFgTpj v+RaTLZC9dpagTmN5tP+7R6JsA7HmG5uFNpLd2a5topZCq4DJWuNYkIoDi9hIwtmd3Bo Q53LWKtQf3j7yzYn55YM7h3VV8IF8lqIWI0+QWAuCWTCizVb4cecOXnc+9p8OA5EhJak wYqg== X-Gm-Message-State: AOJu0YznWU7slku7R7X3B9EbUt1ub5pRhOebPUfg5HoI/eyjgeZMe76N Kwo9Hoerwko6ho9NkMHeGDXrv/bi7eRBjb3yi30+p30lVVfNubPIMM7vSUOH70cmWRFxs3TUsoH 5Yno78liJoFGR9DpvebwNI82SHkf6in3lvBY66d2X X-Gm-Gg: ATEYQzyuV8mQ08wDZGb3jyI3KOpYMz3++LEMMa2l3OBKC+ipy9k1b8X8OG5Vr2TFteL 4QoYxWBvXRGCMl7N0rxehcIxYZi60TxzICcnA2ZIF1miykLOn6idU3qdR/N7zEIZNgFy8uYS2Ou u6hc+VLFJNnCl2OLSo5lK4KWTvY8lMEJhDZuYGFKhLQqtaacQtR+xGzj0/fKCmdHvnptwC+7pje goop2OzWZwajtWKCtWA/LHSYZPNeOxXqPAV7RnJokzjvqVegIx5G7oq1N8ybuFSbFY0oNGMehod xlLh4Q4gqQ== X-Received: by 2002:a05:6214:1254:b0:895:9df:cea5 with SMTP id 6a1803df08f44-899d1da4c22mr11992426d6.27.1772143028279; Thu, 26 Feb 2026 13:57:08 -0800 (PST) MIME-Version: 1.0 References: <3720B2E1-0B96-4063-8D63-B5AE6AFEA159@gmail.com> In-Reply-To: From: Jacob Champion Date: Thu, 26 Feb 2026 13:56:56 -0800 X-Gm-Features: AaiRm50II14jDF9TzqlN-FV-OfZRWe7BFxZjFlLwJdG4Gtj8ZTceYx1R0GxKFXY Message-ID: Subject: Re: [oauth] Stabilize the libpq-oauth ABI (and allow alternative implementations?) To: Zsolt Parragi Cc: PostgreSQL Hackers , Chao Li Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Wed, Feb 25, 2026 at 9:16=E2=80=AFAM Zsolt Parragi wrote: > How would this work with library clients exactly (and even multiple > library clients)? The global setting? Not very well at all. The eventual solution needs to be per-connection. I don't think any version of v3-0006 is likely to make it for PG19, for the record. I just need to ensure that the use case we're moving towards continues to work with the code that's actually committed, and there still might be some pieces that should be cherry-picked backwards in the set. As I said in my original post: > That brings us to patch [v1-]0007, which experimentally promotes the stab= le > API to a public header, and introduces a really janky environment > variable so that people don't have to play games. It will be obvious > from the code that this is not well-baked yet. My hope was to continue to take small steps in the direction of the end goal with every release, but I think PGOAUTHMODULE is a step too far. I don't want to expose an oauth_module connection option, and an environment variable that can't be subsumed by a future connection option will just be cruft eventually. For 19, bleeding-edge developers who want a global override ASAP can implement the public API and tell their application's linker to find a different libpq-oauth. If a global override isn't good enough, PGOAUTHMODULE wouldn't have helped anyway. > * Language bindings: there's already ongoing work on adding support > for the hooks into these libraries, so that's not really a use case (The hooks are probably insufficient in the general case [1], but a global envvar isn't intended to solve that.) > * postgres CLI tools: That's one use case, but it could work without > generic user-facing plugin support, limited to these tools. Yes. > * postgres_fwd/dblink and similar: I'm not sure how that would work, > what if different extensions require different plugins? This already > seems like a tricky question with the hooks We don't support proxied OAuth at all yet (i.e. both of those extensions outright prohibit oauth_* settings). > I can't just download > a binary application, and a separate oauth plugin, and use them > together, I need admin permission - that seems strange to me. Why does that seem strange? If you don't have the ability to install libpq to begin with, you shouldn't be able to modify that libpq or get it to run arbitrary code. If you control the application, on the other hand, you control both the global hook and the link behavior (you don't have to link against system libpq, after all), so it doesn't seem like you've lost any functionality. > An easy solution could be using secure_getenv instead of getenv, which > would at least improve the situation? I don't think we claim setuid-safety for libpq. (Our own code aside, we'd have to vet all of our transitive dependencies in perpetuity.) > And a few specific comments about the patches: Thank you for the review! > +oom: > + request->error =3D libpq_gettext("out of memory"); > + return -1; > > Shouldn't this also free conninfo if it is allocated? Yep, good catch. > +/* Features added in PostgreSQL v19: */ > +/* Indicates presence of PQgetThreadLock */ > +#define LIBPQ_HAS_GET_THREAD_LOCK > > Should this be defined to 1? Yes. One of my weirder copy-paste errors... > + if ((lockerr =3D pthread_mutex_lock(&init_mutex)) !=3D 0) > + { > + /* Should not happen... but don't continue if it does. */ > + Assert(false); > > - libpq_append_conn_error(conn, "failed to lock mutex (%d)", lockerr); > - return 0; > - } > + libpq_append_conn_error(conn, "failed to lock mutex (%d)", lockerr); > + return 0; > + } > > Shouldn't this path return -1, We could. I chose zero to try to retain the PG18 behavior, but I could expand this error message and set request->error instead. If that'd be less confusing to you as a reader, it's probably worth the change. > and also dlclose the library? I don't think we gain anything by that, do we? It's named correctly, it has the right symbols, and the shouldn't-happen-failure-that-happened had nothing to do with the library implementation. > Shouldn't dlcloses also reset state->flow_module after? That'd probably be kinder to anyone expanding this logic in the future, yeah. Maybe not worth a backpatch though (there's no users outside of this function; it's only retained to assist with debugging at the moment). > -free_async_ctx(PGconn *conn, struct async_ctx *actx) > +free_async_ctx(PGoauthBearerRequestV2 *req, struct async_ctx *actx) > > req (or conn) doesn't seem to be used in this function, does it need > that parameter? Ah, right, it's dead now that req->error isn't set. Thanks! > + env =3D strchr(env, '\x01'); > + *env++ =3D '\0'; > > Isn't mutating environment variables UB? Kinda, or at least it invites UB later on according to POSIX. I should just make a copy. Thanks, --Jacob [1] https://github.com/ged/ruby-pg/pull/693#issuecomment-3867178201