Skip to content

Add support for lambda or Proc :password key in connection Hash#701

Open
jawj wants to merge 1 commit intoged:masterfrom
jawj:master
Open

Add support for lambda or Proc :password key in connection Hash#701
jawj wants to merge 1 commit intoged:masterfrom
jawj:master

Conversation

@jawj
Copy link

@jawj jawj commented Feb 24, 2026

This short PR adds support for a lambda or Proc :password value in Postgres connection parameters.

This is useful for services like RDS or Lakebase that can be configured to require short-lived tokens as Postgres passwords.

For precedent, three major JS drivers (node-postgres, postgres.js, Bun.SQL) support the equivalent feature, passing a JS function as the password. For example: brianc/node-postgres#1926

It's certainly possible I've gone about this the wrong way for ruby-pg but, if so, perhaps we can figure out the right way!

@larskanis
Copy link
Collaborator

IMHO the benefit of using the lambda password is zero:

pr = proc{ "password" }
PG.connect(password: pr)

compared to:

pr = proc{ "password" }
PG.connect(password: pr.call)

The only difference is at PG::Connection#reset, which would refresh the password from the lambda. But #reset is just for convenience. It can equally be replaced by a new PG.connect.

Is it the #reset function you want to support with refreshed password? Your description doesn't describe a clear reason, neither the linked issue does.

@jawj
Copy link
Author

jawj commented Feb 25, 2026

In this simple case where you're manually creating a single connection, I guess you're right: the key benefit is that PG::Connection#reset works properly. That's non-zero, but certainly small.

The key scenario where a Proc or lambda for the :password key is useful is when using a connection pool, such as provided by ActiveRecord, Sequel, or the connection_pool gem.

A pool connects (and disconnects) clients on-demand, potentially over long periods between app restarts, using connection parameters supplied at app startup. That makes them tricky to use with the short-lived password tokens that may be provided by e.g. RDS, Google Cloud SQL, Azure or Lakebase — unless the Postgres password can be specified dynamically.

It would instead be possible to build in support for dynamic passwords separately in every pooler, I suppose. But it seems much more efficient and consistent to do it in the driver itself. And it don't think it needs to add a lot of code to maintain.

@jawj
Copy link
Author

jawj commented Feb 25, 2026

I should maybe also clarify that the value of something like pr = proc { "password" } is nil, of course.

In practice, a Proc or lambda is going to be used to retrieve a token from a local cache, refresh it via an API over HTTPS, and so on.

And it's quite nice to be able encapsulate this sort logic. For example, a Postgres provider's SDK can then supply connection parameters that include a dynamic password, and the developer using the SDK doesn't have to worry about token refresh: they can just use these connection parameters anywhere in the same way they normally would.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants