Dynamic user authentication & passthrough auth
This release adds auth_query — dynamic password lookup from PostgreSQL at connection time, eliminating the need to list every user in the config. It also introduces passthrough authentication as the default mode for both static and dynamic users: PgDoorman reuses the client's cryptographic proof
(MD5 hash or SCRAM ClientKey) to authenticate to the backend, so server_password is no longer needed in most setups.
New Features
-
auth_query— dynamic user authentication: Authenticate users by querying PostgreSQL (pg_shadow, custom tables, orSECURITY DEFINERfunctions) at connection time. The query must return a column namedpasswd,password, or any single column containing an MD5 or SCRAM-SHA-256 hash. -
Passthrough authentication (default): PgDoorman reuses the client's cryptographic proof to authenticate to the backend automatically — no plaintext passwords in config. Works for both static users (hash in config) and dynamic users (hash from
auth_query).server_username/server_passwordare
only needed when the backend user differs from the pool user. -
Two auth_query modes:
- Passthrough (default) — each dynamic user gets their own backend connection pool and authenticates as themselves
- Dedicated (
server_userset) — all dynamic users share a single backend pool under one PostgreSQL role
-
Auth query caching: DashMap-based cache with configurable TTL, double-checked locking, rate-limited refetch, and request coalescing. Separate TTLs for successful and failed lookups.
-
SHOW AUTH_QUERYadmin command: Per-pool metrics — cache entries/hits/misses, auth success/failure counters, executor stats, dynamic pool count. -
Prometheus metrics: New metric families
pg_doorman_auth_query_cache,pg_doorman_auth_query_auth,pg_doorman_auth_query_executor,pg_doorman_auth_query_dynamic_pools. -
Idle dynamic pool GC: Background task cleans up expired dynamic pools. Zero overhead for static-only configs.
-
Smart password column lookup: Column resolved by name (
passwd→password→ single-column fallback).
Improvements
-
server_username/server_passwordnow optional: Previously documented as required for MD5/SCRAM hash configs. Now only needed for username mapping or JWT auth. -
Data-driven config & docs generation:
fields.yamlis the single source of truth for all config parameter descriptions (EN/RU). Reference docs, annotated configs, and inline comments are all generated from it.
Quick start
pools:
mydb:
server_host: "127.0.0.1"
server_port: 5432
pool_mode: "transaction"
auth_query:
query: "SELECT passwd FROM pg_shadow WHERE usename = $1"
user: "doorman_auth"
password: "auth_password"Or with static users (no server_password needed):
users:
- username: "app"
password: "md5..." # hash from pg_authid
pool_size: 40