Is your feature request related to a problem?
Temporal can refresh the DB password at runtime (cfg.PasswordCommand → a refreshable DSN),
but the username is fixed in static config. Credential systems that rotate both fields
per lease — HashiCorp Vault's database secrets engine (per-lease users like entity:serv-xxxx) —
therefore cannot be used without a pod restart on every rotation. This is the sibling of #9156:
both need credentials re-resolved at runtime, but #9156 rotates a token (password-like) while
this rotates the username too.
What already exists (main)
common/persistence/sql/sqlplugin/db_handle.go — DatabaseHandle.connect func() (*sqlx.DB, error)
is re-invoked on every reconnect(force); ConvertError triggers reconnect(true) on
needsRefresh(err) and on connection errors (ErrBadConn, EOF,
ECONNRESET/ECONNABORTED/ECONNREFUSED). Combined with MaxConnLifetime, connections are
periodically rebuilt and the connect callback re-runs.
common/persistence/sql/sqlplugin/postgresql/session/session.go — createConnection already
supports a refreshable DSN via cfg.PasswordCommand → CreateRefreshableConnection(buildDSN).
The gap
buildDSN reads cfg.User as a static value, so even the refreshable path only refreshes the
password. There is no equivalent of PasswordCommand for the username.
Proposed solution
Extend the refreshable-credentials mechanism so the username is re-read on each connect() —
e.g. a UserCommand (analogous to PasswordCommand) or a credentials-provider that yields both
username and password at DSN-build time. On reconnect (driven by MaxConnLifetime or
ConvertError), the pool then re-authenticates with the rotated username+password without a
restart. This reuses the existing DatabaseHandle.reconnect() + PasswordCommand infrastructure,
generalizing the password refresh already present.
Environment
Version: v1.31.2 (mechanism unchanged on main). Plugin: postgres12 / postgres12_pgx.
Credentials: Vault per-lease username+password delivered as a K8s Secret by the Vault Secrets
Operator.
Related
Is your feature request related to a problem?
Temporal can refresh the DB password at runtime (
cfg.PasswordCommand→ a refreshable DSN),but the username is fixed in static config. Credential systems that rotate both fields
per lease — HashiCorp Vault's database secrets engine (per-lease users like
entity:serv-xxxx) —therefore cannot be used without a pod restart on every rotation. This is the sibling of #9156:
both need credentials re-resolved at runtime, but #9156 rotates a token (password-like) while
this rotates the username too.
What already exists (main)
common/persistence/sql/sqlplugin/db_handle.go—DatabaseHandle.connect func() (*sqlx.DB, error)is re-invoked on every
reconnect(force);ConvertErrortriggersreconnect(true)onneedsRefresh(err)and on connection errors (ErrBadConn,EOF,ECONNRESET/ECONNABORTED/ECONNREFUSED). Combined withMaxConnLifetime, connections areperiodically rebuilt and the connect callback re-runs.
common/persistence/sql/sqlplugin/postgresql/session/session.go—createConnectionalreadysupports a refreshable DSN via
cfg.PasswordCommand→CreateRefreshableConnection(buildDSN).The gap
buildDSNreadscfg.Useras a static value, so even the refreshable path only refreshes thepassword. There is no equivalent of
PasswordCommandfor the username.Proposed solution
Extend the refreshable-credentials mechanism so the username is re-read on each
connect()—e.g. a
UserCommand(analogous toPasswordCommand) or a credentials-provider that yields bothusername and password at DSN-build time. On reconnect (driven by
MaxConnLifetimeorConvertError), the pool then re-authenticates with the rotated username+password without arestart. This reuses the existing
DatabaseHandle.reconnect()+PasswordCommandinfrastructure,generalizing the password refresh already present.
Environment
Version: v1.31.2 (mechanism unchanged on
main). Plugin:postgres12/postgres12_pgx.Credentials: Vault per-lease username+password delivered as a K8s Secret by the Vault Secrets
Operator.
Related
credential-resolution need; notes
DatabaseHandle.reconnect()already re-runs the connectcallback).
buildDSNinterpolatescfg.Userraw, breaking usernames with:)— tracked separately.