PostgreSQL 18 is the first major PostgreSQL release with built-in OAuth support. This guide walks through a complete PostgreSQL 18 OAuth authentication setup, from installing the right packages to connecting with psql and real application clients using a bearer token.
PostgreSQL 18 OAuth: Configure pg_hba.conf, Validators, and Client Auth
Table of Contents
- What Is PostgreSQL 18 OAuth Authentication Setup
- Prerequisites
- Step 1: Install PostgreSQL 18 and OAuth Client Support
- Step 2: Set Up an OAuth Provider (Keycloak Example)
- Step 3: Install and Enable the OAuth Validator Module
- Step 4: Configure pg_ident.conf for User Mapping
- Step 5: Configure pg_hba.conf for OAuth
- Step 6: Restart PostgreSQL and Watch the Logs
- Step 7: Connect With psql Using a Bearer Token
- Step 8: Test With an Application Client (libpq)
- Fallback Authentication for OAuth Failures
- Conclusion

What Is PostgreSQL 18 OAuth Authentication Setup
Before PostgreSQL 18, clients logged in with passwords, certificates, LDAP, or similar methods stored on the database itself.
A PostgreSQL 18 OAuth authentication setup changes that. The client sends a bearer token from an outside identity provider, like Keycloak or Okta, instead of a password. PostgreSQL does not check this token itself; it passes the token to a small program called a validator module, which asks the identity provider if the token is still valid.
This matters because many teams already manage user identity in one central system. With native OAuth, you can let PostgreSQL trust that same system instead of keeping a separate set of database passwords for every employee or service.
Prerequisites
You need the following requirements before you start PostgreSQL 18 OAuth authentication setup:
- A Linux server running PostgreSQL 18 or newer. Many teams run this test on a Linux VPS built for database workloads, which gives full root access to edit server files.
- Docker installed to run the test Keycloak identity provider without a manual install.
- PostgreSQL compiled or packaged with
--with-libcurland--with-opensslsupport. Official PostgreSQL packages from the PGDG repository already include this. - The
libpq-oauthpackage on the client side, which adds the OAuth device flow topsqlandlibpq. - An OAuth/OIDC provider you control for testing, such as Keycloak running in Docker.
- An OAuth validator module, since PostgreSQL core does not ship one. This guide uses the
open-source pg_oidc_validatorfrom Percona as a working example. - Root or sudo access to edit
postgresql.conf,pg_hba.conf, andpg_ident.conf.
Step 1: Install PostgreSQL 18 and OAuth Client Support
If you are testing with Docker, you can use the command below to pull the official image:
If you are installing on a real Linux VPS instead, add the PGDG repo and install PostgreSQL 18:
Then, install the OAuth client library so psql can talk to an OAuth provider:
Without libpq-oauth, psql can't run the device flow, so the connection just fails with an authentication error. Every machine running psql or a custom client needs this package for a working PostgreSQL 18 OAuth authentication setup.
If you plan to host this server long-term, doing the whole setup on a dedicated Linux VPS with restricted network access makes it much easier to control which IP ranges can even reach port 5432 before OAuth is checked.
Step 2: Set Up an OAuth Provider (Keycloak Example)
PostgreSQL needs an outside identity provider to issue and check tokens. Here we use Keycloak as an example that runs easily in Docker. Run Keycloak in Docker:
Open http://127.0.0.1:8080 and log in with admin/admin. Inside the default "master" realm, do two things:
- Add a test user. Go to Users, click Add user, enter a username and email, save, open the Credentials tab, and set a password with "Temporary" turned off.
- Add a client for PostgreSQL. Go to Clients, click Create client, set Client ID to postgres, and under Capability config, enable only "OAuth 2.0 Device Authorization Grant." Leave the URL fields blank and save.
Note the container's internal IP address, since the PostgreSQL server needs to reach the issuer URL:
This IP becomes part of your issuer URL, for example http://172.17.0.3:8080/realms/master.
Step 3: Install and Enable the OAuth Validator Module
PostgreSQL core cannot validate a bearer token on its own, because every identity provider signs and formats tokens differently. You must install a validator module. Inside your PostgreSQL container or server:
Confirm the shared library is in the right folder:
You should see /usr/lib/postgresql/18/lib/pg_oidc_validator.so in the output.
Now tell PostgreSQL to load it. Edit postgresql.conf:
Add or update these two lines:
authn_field tells the validator which token field to use as the user's identity. email works well with Keycloak, since the "profile" scope includes it. For Microsoft Entra, use unique_name or upn instead, since Entra tokens don't include email the same way.
Step 4: Configure pg_ident.conf for User Mapping
OAuth tokens carry an external identity, like an email address, not a PostgreSQL role name. pg_ident.conf maps that external identity to a real database role. Open the file to add a mapping:
This example maps anyone with an email ending in @mydomain.com to the shared role employees:
Then, create that role in the database if it does not exist yet:
Step 5: Configure pg_hba.conf for OAuth
This is the core of any PostgreSQL 18 OAuth authentication setup. Open the pg_hba.conf file:
Add a line using the new oauth method, above any catch-all rules:
issuermust be an HTTPS URL in production. It must exactly match the issuer string in the provider's discovery document, byte for byte, with no case differences.scopelists which OAuth scopes the client must request.profileis enough for a simple Keycloak test since it includes the email claim.mappoints to the identity mapping name you created inpg_ident.conf.validatoris only required whenoauth_validator_librarieslists more than one library.
A correct PostgreSQL 18 OAuth authentication setup always limits the ADDRESS column to a known network range, not 0.0.0.0/0. This way, only trusted subnets can even try an OAuth login.
Step 6: Restart PostgreSQL and Watch the Logs
Apply the new configuration with the following command:
If you are using Docker, use this command instead:
Keep the log open in a second terminal while you test:
Watching the log while testing your connection is the fastest way to see the exact reason it was rejected.
Step 7: Connect With psql Using a Bearer Token
Now connect from a client machine using psql and the new oauth_issuer and oauth_client_id connection parameters:
Since the test issuer is plain HTTP, PostgreSQL 18 will reject the discovery request by default, because OAuth discovery URLs must use HTTPS. For local testing only, you can bypass this using a debug flag:
psql will print a URL and a short code, similar to this:
Open that link in a browser, log in as your test user, and approve access for the postgres client. Once approved, psql finishes the connection automatically and you are in a normal SQL prompt.
Note: Never use PGOAUTHDEBUG=UNSAFE outside of a local test server. It prints raw tokens and secrets to your terminal, and anyone who reads that output can reuse your session.
Step 8: Test With an Application Client (libpq)
Applications built on libpq use the same connection parameters as psql. A minimal connection string looks like this:
For apps that can't open a browser, like background jobs or cron scripts, use libpq's PQAUTHDATA_OAUTH_BEARER_TOKEN hook instead of the device flow. Your app fetches a token itself from the identity provider using a service account, then hands that token to libpq directly; no human needs to click a link.
This is the right pattern for microservices in a real PostgreSQL 18 OAuth authentication setup.
Fallback Authentication for OAuth Failures
Don't rely on OAuth alone from day one. You must keep a backup rule in pg_hba.conf using scram-sha-256, limited to a trusted source like a jump host or admin subnet:
This gives you a way back in if the identity provider goes down, the validator crashes, or a bad issuer locks everyone out. Test this rule before you need it, not during an outage. Once your PostgreSQL 18 OAuth authentication setup runs cleanly for a while, you can tighten it. But most teams keep a minimal backup login permanently.
Conclusion
A working PostgreSQL 18 OAuth authentication setup has five parts, including the OAuth provider, a validator module, pg_hba.conf, pg_ident.conf, and the client's connection string. Get the issuer and scope right, match your validator to your identity provider, and always keep a backup login method.
Once these pieces are configured, both psql and your apps can log in with a short-lived token instead of a stored password.
We hope you enjoy this guide. For more detailed information, you can check the PostgreSQL 18 OAuth Documentation.