Re: Continuous re-validation of session credentials
Re: Continuous re-validation of session credentials
changes to 0002-0005):
1. Standby servers
CheckCredentialValidity() no longer skips validation under
RecoveryInProgress(). Hot-standby sessions run continuously "in
recovery", so this was silently disabling the feature for read
replicas -- all the checks involved are read-only/local, so
there's no reason to exclude them.
2. Set Session Authorization
ValidateRoleValidity() now checks GetAuthenticatedUserId()
instead of GetSessionUserId(), so a superuser can't mask the
login role's expiry/removal by switching session authorization.
This also keeps it consistent with the method-specific
validators, which always check the fixed login identity. Added
regression coverage.
EnableCredentialValidationTimeout() and CheckCredentialValidity()
now explicitly skip AmWalSenderProcess()
Hi,
Following up on the ongoing work for continuous credential validation, I would like to propose the next two patches in the series.
These patches extend the continuous validation framework to handle both GSSAPI/Kerberos and LDAP (Search+Bind) authenticated sessions.
Patch 4/5: Add GSS credential expiry to credential validation
This patch introduces method-specific validation for GSSAPI/Kerberos sessions (
CVT_GSS).The GSS security context established at authentication carries a lifetime derived from the client's Kerberos ticket. We introduce a helperbe_gssapi_get_context_expired()which utilizesgss_context_time()on the acceptor context retained on thePort. This is a purely local check that requires no round-trip to the KDC. If the context lifetime has elapsed, the session is safely terminated.
postgres=> select system_user; system_user ----------------------- gss:test1@EXAMPLE.COM (1 row) postgres=> select current_user; current_user -------------- test1
postgres=> select current_time;
FATAL: session credentials have expired
HINT: Please reconnect to establish a new authenticated session.
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
The connection to the server was lost. Attempting reset: Failed.
(1 row)Patch 5/5: Add LDAP account-existence check to credential validation
This patch adds validation support for LDAP sessions (
CVT_LDAP).Unlike token- or certificate-based authentication, an LDAP session does not retain a credential with an intrinsic expiry date. Instead, "validity" is defined as the account's continued existence within the directory.
During each validation cycle, the backend connects and re-binds using the configured search credentials (
ldapbinddn/ldapbindpasswd), then re-runs the configured search filter. If the search yields exactly zero entries, the account is considered deleted or disabled, and the session is terminated.
postgres=> SELECT current_user;
current_user
--------------
test1
(1 row)
postgres=> select system_user;
system_user
----------------------------------
ldap:uid=test1,dc=example,dc=net. <= After this I fired ldapdelete and got validation error on next validation cycle
(1 row)
postgres=> select current_time;
FATAL: session credentials have expired
HINT: Please reconnect to establish a new authenticated session.
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
The connection to the server was lost. Attempting reset: Failed.
(1 row)Thanks & Best regards,
Ajit
On Fri, 26 Jun 2026 at 11:21, Ajit Awekar <ajitpostgres@gmail.com> wrote:Hi,Attached is v2 of the patch set, rebased on the current master.The only functional change from the previous version is a fix for thecfbot failure. The earlier version src/test/modules/test_misc/t/003_check_guc.pldue to the tab in the trailing spaces.Thanks & Best Regards,AjitOn Tue, 16 Jun 2026 at 17:44, Ajit Awekar <ajitpostgres@gmail.com> wrote:Hi,
Today PG validates a client's credentials only once, at connection
time. After that the backend runs until the client disconnects, even if the
basis for the original authentication decision has gone away. In particular:
- the role's VALID UNTIL passes, or the role is dropped (ALTER ROLE ...
VALID UNTIL / DROP ROLE);
- the OAuth bearer token the session authenticated with expires;
- the TLS client certificate the session authenticated with reaches its
notAfter date.
In all of these cases a long-lived session keeps running with credentials that
would be rejected on a fresh connection. For environments with short-lived
credentials (OAuth tokens, short-lived certs, time-boxed accounts) this is a
real gap: revoking access has no effect on already-established sessions.
This patch series adds an optional mechanism to periodically re-validate the
credentials of an active session and terminate it (FATAL) once they are no
longer valid.A per-backend timer (CREDENTIAL_VALIDATION_TIMEOUT) fires every
credential_validation_interval seconds and sets a pending flag.Validation has two layers:
- A baseline, auth-method-independent check (role still exists and has not
passed rolvaliduntil), applied to every authenticated session.
- Optional method-specific validators, registered via
RegisterCredentialValidator(), for OAuth token expiry and client
certificate expiry.The framework is deliberately extensible: adding re-validation for a newauthentication method needs only three small steps -- add a
CredentialValidationType, implement a "bool validator(void)" callback that
returns whether the credential is still valid, and register it with
RegisterCredentialValidator(). The certificate and OAuth validators in 0002and 0003 are themselves examples of plugging into the framework this way,so methods such as LDAP, RADIUS, or GSSAPI/Kerberos credential lifetimescould be added later without touching the core.Two GUCs :credential_validation_enabled (bool, default off)
credential_validation_interval (int, 5..3600 s, default 60)Patch series------------
0001 Framework + baseline role-validity check (rolvaliduntil / role
existence). Useful on its own for password/md5/scram sessions.
0002 TLS client certificate expiry. The cert presented at connect time is
retained on the Port, so its notAfter is re-checked locally with no
network round-trip.
0003 OAuth token expiry. This adds an optional expire_cb callback to
OAuthValidatorCallbacks; to stay ABI-compatible the validator magic is
versioned (V1 = existing layout, V2 = adds expire_cb), and the server
accepts both.Request a review.Thanks & Best Regards,Ajit
Re: Continuous re-validation of session credentials
Hi,
Today PG validates a client's credentials only once, at connection
time. After that the backend runs until the client disconnects, even if the
basis for the original authentication decision has gone away. In particular:
- the role's VALID UNTIL passes, or the role is dropped (ALTER ROLE ...
VALID UNTIL / DROP ROLE);
- the OAuth bearer token the session authenticated with expires;
- the TLS client certificate the session authenticated with reaches its
notAfter date.
In all of these cases a long-lived session keeps running with credentials that
would be rejected on a fresh connection. For environments with short-lived
credentials (OAuth tokens, short-lived certs, time-boxed accounts) this is a
real gap: revoking access has no effect on already-established sessions.
This patch series adds an optional mechanism to periodically re-validate the
credentials of an active session and terminate it (FATAL) once they are no
longer valid.A per-backend timer (CREDENTIAL_VALIDATION_TIMEOUT) fires every
credential_validation_interval seconds and sets a pending flag.Validation has two layers:
- A baseline, auth-method-independent check (role still exists and has not
passed rolvaliduntil), applied to every authenticated session.
- Optional method-specific validators, registered via
RegisterCredentialValidator(), for OAuth token expiry and client
certificate expiry.The framework is deliberately extensible: adding re-validation for a newauthentication method needs only three small steps -- add a
CredentialValidationType, implement a "bool validator(void)" callback that
returns whether the credential is still valid, and register it with
RegisterCredentialValidator(). The certificate and OAuth validators in 0002and 0003 are themselves examples of plugging into the framework this way,so methods such as LDAP, RADIUS, or GSSAPI/Kerberos credential lifetimescould be added later without touching the core.Two GUCs :credential_validation_enabled (bool, default off)
credential_validation_interval (int, 5..3600 s, default 60)Patch series------------
0001 Framework + baseline role-validity check (rolvaliduntil / role
existence). Useful on its own for password/md5/scram sessions.
0002 TLS client certificate expiry. The cert presented at connect time is
retained on the Port, so its notAfter is re-checked locally with no
network round-trip.
0003 OAuth token expiry. This adds an optional expire_cb callback to
OAuthValidatorCallbacks; to stay ABI-compatible the validator magic is
versioned (V1 = existing layout, V2 = adds expire_cb), and the server
accepts both.Request a review.Thanks & Best Regards,Ajit