Hi,

While working on a validator for keycloak[1] with libpq-oauth I find
out that to allow a self-signed certificated I had to set the CA on the
client but for this was required to also set the PGOAUTHDEBUG=UNSAFE
which generated a lot of information on the client side that I didn't
need for my testing and work.

This patch basically remove the need of setting the PGOAUTHDEBUG=UNSAFE
to be able to use PGOAUTHCAFILE.

I'm not sure if where I put the documentation is the right place, I
would like to have some opinions on that matter too.


[1] https://github.com/cloudnative-pg/postgres-keycloak-oauth-validator

-- 
Jonathan Gonzalez V. <[email protected]>
From b32a1ad93f933fa319ff29e15299659d67de4d22 Mon Sep 17 00:00:00 2001
From: "Jonathan Gonzalez V." <[email protected]>
Date: Wed, 29 Oct 2025 16:54:42 +0100
Subject: [PATCH v1 1/1] libpq-oauth: allow changing the CA when not in debug
 mode

Allowing to set a CA enables users environment like companies with
internal CA or developers working on their own local system while
using a self-signed CA and don't need to see all the debug messages
while testing inside an internal environment.

Signed-off-by: Jonathan Gonzalez V. <[email protected]>
---
 doc/src/sgml/libpq.sgml                 | 23 +++++++++++++++++------
 src/interfaces/libpq-oauth/oauth-curl.c | 20 +++++++-------------
 2 files changed, 24 insertions(+), 19 deletions(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 5bf59a19855..c3fe9d5478a 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -10520,12 +10520,6 @@ typedef struct PGoauthBearerRequest
        permits the use of unencrypted HTTP during the OAuth provider exchange
       </para>
      </listitem>
-     <listitem>
-      <para>
-       allows the system's trusted CA list to be completely replaced using the
-       <envar>PGOAUTHCAFILE</envar> environment variable
-      </para>
-     </listitem>
      <listitem>
       <para>
        prints HTTP traffic (containing several critical secrets) to standard
@@ -10547,6 +10541,23 @@ typedef struct PGoauthBearerRequest
     </para>
    </warning>
   </sect2>
+  <sect2 id="libpq-oauth-environment">
+   <title>Environment variables</title>
+   <para>
+    The behavior of the OAuth calls may be affected by the following variables:
+    <variablelist>
+     <varlistentry>
+      <term><envar>PGOAUTHCAFILE</envar></term>
+      <listitem>
+       <para>
+        Allows to specify the path to a CA file that will be used by the client
+        to verify the certificate from the OAuth server side.
+       </para>
+      </listitem>
+     </varlistentry>
+    </variablelist>
+   </para>
+  </sect2>
  </sect1>
 
 
diff --git a/src/interfaces/libpq-oauth/oauth-curl.c b/src/interfaces/libpq-oauth/oauth-curl.c
index aa50b00d053..b27a269c962 100644
--- a/src/interfaces/libpq-oauth/oauth-curl.c
+++ b/src/interfaces/libpq-oauth/oauth-curl.c
@@ -1704,6 +1704,8 @@ debug_callback(CURL *handle, curl_infotype type, char *data, size_t size,
 static bool
 setup_curl_handles(struct async_ctx *actx)
 {
+	const char *env;
+
 	/*
 	 * Create our multi handle. This encapsulates the entire conversation with
 	 * libcurl for this connection.
@@ -1792,20 +1794,12 @@ setup_curl_handles(struct async_ctx *actx)
 	}
 
 	/*
-	 * If we're in debug mode, allow the developer to change the trusted CA
-	 * list. For now, this is not something we expose outside of the UNSAFE
-	 * mode, because it's not clear that it's useful in production: both libpq
-	 * and the user's browser must trust the same authorization servers for
-	 * the flow to work at all, so any changes to the roots are likely to be
-	 * done system-wide.
+	 * Allow to change the trusted CA even if we're not in debug mode, this help
+	 * to make it easy to work on environments were the CA could internal and
+	 * not available on every system, like big companies with airgap systems.
 	 */
-	if (actx->debugging)
-	{
-		const char *env;
-
-		if ((env = getenv("PGOAUTHCAFILE")) != NULL)
-			CHECK_SETOPT(actx, CURLOPT_CAINFO, env, return false);
-	}
+	if ((env = getenv("PGOAUTHCAFILE")) != NULL)
+		CHECK_SETOPT(actx, CURLOPT_CAINFO, env, return false);
 
 	/*
 	 * Suppress the Accept header to make our request as minimal as possible.
-- 
2.51.0

Reply via email to