Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
Sometimes passwords leak. Also sometimes security teams want infrastructure teams to rotate passwords. With Postgres, that's impossible currently without taking down the application or using third-party tools like Vault. If one was to change the password today, all new connections will be denied, causing a production incident.
Solution
This PR introduces the ability to use multiple passwords (called secrets) to connect to PgCat while one secret is being deprecated and replaced with the other. Each database <--> user <--> secret triplet gets their own connection pool (before, it was only database <--> user, like PgBouncer).
Creating separate pools is a good idea because it allows us to:
Implementation caveats
All Postgres authentication mechanisms except plain text obfuscate the secret (password) being used, so without knowing more, we need to test all configured passwords. Additionally, we can't (I think) come up with a unique pool identifier using a hashed password, since the hashing has to be deterministic, which defeats the purpose of password hashing (they are random, e.g. md5 creates a different hash every time because of random salt).
So, for this feature to work, we need to use plain text authentication. Of course that will set off all kinds of alarm flags with most people, since this method is not secure by itself (neither is MD5, but that's out of scope at the moment). So, we only allow this mechanism to work if PgCat is configured to use TLS connections. Using TLS and plain text passwords together is safe and used everywhere across the Internet today. If it's good enough for the banks, it's good enough for us.
Postgres docs on plain auth: https://www.postgresql.org/docs/15/auth-password.html
Changes
pgcat.toml
Additional
secrets = [ "one", "two", "three" ]
option is added to[users]
section. This configures multiple passwords (and pools) for the user. Thepassword
option is used to connect to Postgres.admin db
An additional
secret
column is added (redacted) to differentiate pool statistics.Ops
To use this feature:
secrets
for the user, reload the config.secrets
, reload the config.ALTER ROLE ...
in Postgres to change the password, b) changepassword
in config and reload.Step 4 can be done with 0 errors if
min_size
for the pool is set tomax_size
, opening all connections in advance. This ensures no new connection to Postgres is made during step 4. Existing connections using the old password are not affected byALTER ROLE
.