diff --git a/documentation/configuration-utils/_oidc.config.json b/documentation/configuration-utils/_oidc.config.json
index c57d09856..e084545c8 100644
--- a/documentation/configuration-utils/_oidc.config.json
+++ b/documentation/configuration-utils/_oidc.config.json
@@ -90,5 +90,9 @@
"acl.oidc.cache.ttl": {
"default": 30000,
"description": "User info cache entry TTL (time to live) in milliseconds, default value is 30 seconds. For improved performance QuestDB caches user info responses for each valid access token, this settings drives how often the access token should be validated and the user info updated."
+ },
+ "acl.oidc.pg.token.as.password.enabled": {
+ "default": "false",
+ "description": "When enabled, the PGWire endpoint supports OIDC authentication. The OAuth2 token should be sent in the password field, while the username field should contain the string `_sso`, or left empty if that is an option."
}
}
diff --git a/documentation/operations/openid-connect-oidc-integration.mdx b/documentation/operations/openid-connect-oidc-integration.mdx
index 1cda31557..03c8294e7 100644
--- a/documentation/operations/openid-connect-oidc-integration.mdx
+++ b/documentation/operations/openid-connect-oidc-integration.mdx
@@ -348,11 +348,16 @@ The OAuthenticator documentation also contains
using different identity providers.
If Jupyter notebooks are used without JupyterHub, one option for OAuth2
-integration is to use the
-[Resource Owner Password Credentials](https://oauth.net/2/grant-types/password)
-flow. It is likely that to enable this flow in your OAuth2 provider will require
-additional setup. The Resource Owner Password Credentials flow is legacy, and
-should be used as a last resort.
+integration is to use the
+Resource Owner Password Credentials (ROPC) flow.
+It is likely that enabling this flow in your OAuth2 provider will require
+additional setup.
+
+:::caution
+
+The Resource Owner Password Credentials flow is legacy, and should be used as a last resort.
+
+:::
We can use the code below to acquire an access token in our notebook:
@@ -576,6 +581,31 @@ with Sender.from_conf(conf) as sender:
sender.dataframe(df, table_name="foo", at="ts")
```
+## OIDC for the PGWire endpoint
+
+If the
+Resource Owner Password Credentials (ROPC) flow is not an option, we can still authenticate via OIDC on the PGWire endpoint.
+However, in this case the client's responsibility to source the token required for authentication.
+This method works wherever a Postgres client library is available, including jupyter notebooks.
+
+Token authentication for the PGWire endpoint should be enabled by adding the `acl.oidc.pg.token.as.password.enabled=true` setting to the server configuration.
+
+The token should be sent in the password field, while the username field should contain the string `_sso`, or left empty if that is an option:
+
+```python
+import psycopg as pg
+
+token = "token_requested_from_the_oauth2_provider"
+
+conn_str = f"user=_sso password={token} host=localhost port=8812 dbname=qdb"
+with pg.connect(conn_str, autocommit=True) as connection:
+ with connection.cursor() as cur:
+ cur.execute('select current_user()')
+ records = cur.fetchall()
+ for row in records:
+ print(row)
+```
+
## User permissions
QuestDB requires additional user information to be able to construct the user's