Hi All,

I'd like to propose a patch that adds a credential validation framework to
PostgreSQL, enabling periodic re-validation of authentication
 credentials during active sessions.

Currently, PostgreSQL validates credentials only at connection time. Once
authenticated, a session remains valid even if the underlying
credentials expire (e.g., a user's rolvaliduntil passes, or an OAuth token
expires). This can be problematic in environments with strict
security requirements where sessions should be terminated when credentials
become invalid.

This patch introduces a timer-based credential validation mechanism that
periodically checks whether a session's authentication credentials are
 still valid. When credentials are found to be expired, the session is
terminated with an appropriate error message

*Key Components  *

  1. Core Framework (auth-validate.c, auth-validate.h)
    - Manages validation callbacks for different authentication methods
    - Provides a timeout-based scheduler using
CREDENTIAL_VALIDATION_TIMEOUT

    - Handles validation status (CVS_VALID, CVS_EXPIRED, CVS_ERROR)
  2. Validation Methods (auth-validate-methods.c)

    - Password validation: checks rolvaliduntil in pg_authid

    - OAuth validation: delegates to the validator module's new expire_cb
callback
  3. GUC Parameters

    - credential_validation.enabled (boolean, default: false)
    - credential_validation.interval (integer, 1-60 minutes, default: 1)

*OAuth Validator Changes  *


  The patch extends the OAuth validator API with an optional expire_cb
callback. To maintain backward compatibility, the magic version has been
  bumped to PG_OAUTH_VALIDATOR_MAGIC_V2. Existing V1 validators continue to
work; the server simply skips expiration checking for them.


*Example Configuration*
  credential_validation.enabled = on
  credential_validation.interval = 5   # minutes

Thanks & Best Regards,
Ajit


On Mon, 16 Mar 2026 at 19:27, Ajit Awekar <[email protected]> wrote:

> Hi,
>
> Please find the attached first version of the patch providing credential
> validation framework.
>
> The credential validation framework provides a mechanism to continuously
> validate authentication credentials during an active session. This enables
> the server to periodically check credential validity and take appropriate
> action when credentials expire or become invalid.
>
>   Currently, Postgres validates credentials only at connection time. Once
> authenticated, a session remains active even if:
>
>   - A user's rolvaliduntil expiration time passes
>   - An OAuth bearer token expires
>
>
>
> * Proposed Solution*
>   The patch introduces a credential validation framework that:
>
>   1. Periodically checks credential validity during active sessions
>   2. Terminates sessions when credentials expire or become invalid
>
> *Implementation*
>
>   The framework consists of:
>
>   - Core infrastructure (auth-validate.c/h): Manages validation callbacks,
> dispatches validation checks based on authentication method
>   - Method implementations (auth-validate-methods.c/h): Contains
> validators for password-based auth (checks rolvaliduntil in pg_authid) and
> OAuth
>   (delegates to validator's expire_cb)
>
>   Validation is triggered during query execution in both simple and
> extended query protocol paths, using a time-based approach to limit
> overhead.
>
>
> *  Configuration*
>   Two new GUC parameters:
>
>   credential_validation.enabled = false   # enable/disable validation
>   credential_validation.interval = 1      # check interval in minutes
> (1-60)
>
>
> * Extensibility*
>   New authentication methods can be supported by:
>   1. Adding an enum value to CredentialValidationType
>   2. Implementing a validation callback
>   3. Registering it via RegisterCredentialValidator()
>
>
>  Should there be per-authentication-method enable/disable settings?
>
> Thanks & Best Regards,
> Ajit
>
>
> On Fri, 20 Feb 2026 at 15:12, Ajit Awekar <[email protected]> wrote:
>
>>
>> Thanks a lot Daniel, Zslot, Vasuki for your review comments.
>>
>> >The mechanism used is however a secondary discussion,
>> >first thing to get in place is a design for how to handle mid-connection
>> >credential expiration.
>>
>> This patch introduces a generic credential validation framework that
>> allows
>>  us to periodically validate authentication credentials during active
>>  database sessions. When enabled, this feature detects expired
>>  credentials and terminates sessions that are no longer valid.
>>
>>  Added GUCs
>> Credential_validation.enabled = on   // Enable or Disable Credential
>> validation
>> Credential_validation.interval = 120  //Frequency in seconds of running
>> credential validation
>>
>>  The callback mechanism works by:
>>   - Defining a CredentialValidationCallback function pointer type
>>   - Maintaining an array of validators indexed by authentication method
>>   - Allowing other auth mechanisms to register validators via
>>     RegisterCredentialValidator()
>>   - Selecting the appropriate validator at runtime based on the session's
>>     authentication method
>>
>> The current implementation primarily supports password-based
>> authentication methods, verifying that passwords haven't expired. It can be
>> extended to any authentication method.
>> This patch is WIP. I am submitting it now to get early feedback on the
>> overall design and approach.
>>
>> Thanks & Best Regards,
>> Ajit
>>
>> On Wed, 18 Feb 2026 at 22:29, Zsolt Parragi <[email protected]>
>> wrote:
>>
>>> > but I still think that neither should overload
>>> > what FATAL error means
>>>
>>> I see, I misunderstood what you meant by graceful there. In this case,
>>> this is also a good comment for the password expiration thread,
>>> currently that also uses FATAL errors for terminating a connection
>>> when the password expires.
>>>
>>> What other option do you see? Something new for this use case like
>>> GoAway, and clients not understanding it simply get disconnected after
>>> some grace period? Or using the recently merged connectionWarning to
>>> send a warning to the client, and disconnect it shortly if it doesn't
>>> do anything to fix the situation?
>>>
>>> When I tested the password expiration patch I noticed that deleted
>>> users who still have remaining active connections currently get ERRORs
>>> for every statement that requires permission checks, so in this regard
>>> using ERROR/FATAL for the situation seemed fine to me - it's similar
>>> to what already happens in some edge cases with authentication.
>>>
>>

Attachment: Credential_validation.patch
Description: Binary data

Reply via email to