go-pg/pg

Support for Secret Provider.

elliotcourant opened this issue · 1 comments

I'd like to use Vault or some other secret provider in order to authenticate an application to PostgreSQL.

https://www.vaultproject.io/docs/secrets/databases/postgresql

This would allow my application to use rotating credentials to improve security.

I'm curious how this might be implemented with something like go-pg? As it stands right now the config object only supports providing a username and password once, and any hooks that are available or callbacks are after a connection has been made to the database. I could implement some code in my application that rotates the *pg.DB object that it is using periodically, swapping it out for one with a new config.

But I'd like to know if you'd be open to something like a BeforeConnect callback method that could be passed via the config that would allow credentials to be replaced or provided there as well. This way I could simply retrieve my rotating credentials right before a new database connection is established.

@vmihailenco thoughts?

I believe the only practical way is to write an utility that restarts your services when password in Vault is changed. Go supports graceful restarts so the disruptance is minimal even if you rotate your passwords hourly.

I have not tried, but https://github.com/coreos/go-systemd can be helpful.

I could implement some code in my application that rotates the *pg.DB object that it is using periodically, swapping it out for one with a new config.

This is a possibility too as long as you don't use Listener. But sooner or later you will need to use it or find some other package that can't be rotated this way.

But I'd like to know if you'd be open to something like a BeforeConnect callback method that could be passed via the config that would allow credentials to be replaced or provided there as well.

That is a lot of synchronization code that must close existing connections and replace them with new ones. Even just closing the connection pool and creating a new one is a lot of work. But in practice it is more than that (e.g. what to do with running queries). I would not go this way.