github ozontech/pg_doorman v3.3.0
v3.3.0 (Feb 23, 2026)

7 hours ago

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, or SECURITY DEFINER functions) at connection time. The query must return a column named passwd, 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_password are
    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_user set) — 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_QUERY admin 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 (passwdpassword → single-column fallback).

Improvements

  • server_username/server_password now 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.yaml is 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

Don't miss a new pg_doorman release

NewReleases is sending notifications on new releases.