Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic password change #2513

Closed
vitaly-t opened this issue Apr 8, 2021 · 3 comments
Closed

Dynamic password change #2513

vitaly-t opened this issue Apr 8, 2021 · 3 comments

Comments

@vitaly-t
Copy link
Contributor

vitaly-t commented Apr 8, 2021

What is the recommended approach to dealing with passwords that can change dynamically?

At first, I saw this PR, only to find out it is actually useless for this, as it only invokes the callback once, in the beginning. In my case, the password can change at any point, and the pool connection needs to be updated accordingly.

At first, I tried destroying and then re-creating the pool, but this seemed too radical, and awkward, having to track authentication issues to figure out when to re-create the pool.

Then I tried setting pool.options.password = 'new-password' whenever I was about to reuse the pool object. But this would only work when a connection object was used. For a connection string, I had to re-generate the string, and set it to pool.options.connectionString before every use of the pool.

This all looks like a hack. Is there a recommended approach to updating the pool with the new password?

@sehrope
Copy link
Contributor

sehrope commented Apr 8, 2021

No, the dynamic password function is not invoked only once. It's invoked each time an authentication is requested for a client connection. For a pool that would be once per connection at the time the connection created. PostgreSQL only requests authentication once at the beginning of the connection handshake so there's no situation where it would be invoked more than once for the same connection.

Add some logging to your dynamic password function to see if it's being called at all. I bet it's not.

I think the issue here is from using both a connection string and a password function. If you try to use both via something like:

const pool = new pg.Pool({
    connectionString: 'postgresql://user@db.example:5432/my-db',
    password: async () => 'random-' + Date.now(),
})

The connection string parser assigns config.password = undefined:

var auth = (result.auth || ':').split(':')
config.user = auth[0]
config.password = auth.splice(1).join(':')

And then the undefined password in the config from the connection string is overriding any password function:

config = typeof config === 'string' ? parse(config) : config || {}
// if the config has a connectionString defined, parse IT into the config we use
// this will override other default values with what is stored in connectionString
if (config.connectionString) {
config = Object.assign({}, config, parse(config.connectionString))
}

If you instead use a pool with the entire config specified as an object (no connectionString property) it works because the password property is passed as-is to the client.

const pool = new pg.Pool({
    host: 'db.example.com',
    port: 5432,
    user: 'user',
    database: 'my-db',
    password: async () => 'random-' + Date.now(),
});

I think the fix to support mixed configs (both URI and object) is to only set the values in parsed connectionString if they are not undefined.

@JoelVenable
Copy link

@sehrope Excellent! I was searching for this exact issue, because I am looking to migrate from a password environment variable to an IAM role on my AWS RDS db (generates an auth token/password that is only valid for 15 minutes).

However, the documentation does not mention this feature. I'll submit an issue on the docs repo.

JoelVenable added a commit to JoelVenable/node-postgres-docs that referenced this issue Apr 8, 2021
Documentation should mention supported feature.

brianc/node-postgres#2513
@vitaly-t
Copy link
Contributor Author

Ok 👍

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

No branches or pull requests

3 participants