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

Support retrieving db password via callback #1873

Closed
gregplaysguitar opened this issue Apr 8, 2019 · 8 comments
Closed

Support retrieving db password via callback #1873

gregplaysguitar opened this issue Apr 8, 2019 · 8 comments

Comments

@gregplaysguitar
Copy link
Contributor

gregplaysguitar commented Apr 8, 2019

RDS postgres supports connecting via an "IAM Authentication Token", which lasts 15 minutes, and is used as the password when connecting to the database. I can't see any way to connect like this with pg, since the password is a static value passed at pool creation time. Ideally, the pool would be able to retrieve a new password whenever it needs to create a new connection.

I think the ideal API for this would be something like this - note the getPassword function needs to be asynchronous:

const { Pool } = require('pg')

const pool = new Pool({
  user: 'dbuser',
  host: 'database.server.com',
  database: 'mydb',
  getPassword: function () {
    // return a promise which resolves with the generated password
  },
  port: 3211,
})

I am most likely available to work on this issue, but keen to get maintainer approval first before I write any code.

More details here:
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.Connecting.AWSCLI.PostgreSQL.html

@vitaly-t
Copy link
Contributor

vitaly-t commented Apr 9, 2019

Why not just recreate the pool object when you get a new password?

@charmander
Copy link
Collaborator

@vitaly-t Existing connections

@kellertobias
Copy link

Same problem here. Trying to Monkey patch the Client.connect method right now.

@kellertobias
Copy link

kellertobias commented Jul 17, 2019

I am testing the following right now: (Coffeescript)

oldConnect = pg.Client.prototype.connect
pg.Client.prototype.connect = (callback) ->
	console.log "Hallo From Connect :)"
	this.connectionParameters.password = getPassword()
	oldConnect.bind(this)(callback)

@kellertobias
Copy link

Seems to work.

@sehrope
Copy link
Contributor

sehrope commented Jul 17, 2019

@kellertobias That wouldn't work if retrieving the password is an async operation. You would need to wait for it to complete prior to continuing the callback.

I took a peek at the code and turns out this wasn't that bad to add. See #1926 for a PR that adds this feature. It'll need at least one test added prior to being merged, but would be good if you can try it out and see if it works for your use case.

@kellertobias
Copy link

kellertobias commented Jul 17, 2019

Works if using meteor with future/fibers and so making the async operation look sync ;)

@robbiet480
Copy link

This was successfully fixed via #1926. Here's an example:

password: async () => {
  if(process.env.DB_CONNECTION_STYLE === "rds_iam") {
    const signer = new AWS.RDS.Signer({
      region: (new AWS.Config()).region,
      hostname: process.env.DB_HOST,
      port: Number(process.env.DB_PORT),
      username: process.env.DB_USERNAME,
    });
    return signer.getAuthToken({});
  }
  return process.env.DB_PASSWORD;
},

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

No branches or pull requests

6 participants