Keep password out of logs
There are still at least 2 places the DB password could end up in logs:
- Supervisor report:
=SUPERVISOR REPORT==== 13-Dec-2025::10:08:49.329488 ===
supervisor: {<0.614.0>,pgo_connection_sup}
errorContext: child_terminated
reason: killed
offender: [{pid,<0.618.0>},
{id,pgo_connection},
{mfargs,
{pgo_connection,start_link,
[#Ref<0.4151681441.3415867393.163241>,<0.612.0>,
pool_checkout_kill,<0.613.0>,
#{user => "test",password => "password",
pool_size => 10,database => "test"}]}},
{restart_type,permanent},
{significant,false},
{shutdown,100},
{child_type,worker}]
- Crashes by any code using a checked out connection.
(2) can be fixed by removing the password from the connection state passed to the user.
(1) I think can be solved by changing connection startup slightly:
[{ok, _} = pgo_connection_sup:start_child(ConnSup) || _ <- lists:seq(1, Size)],
[begin
{ok, Pid} = pgo_connection_sup:start_child(ConnSup)
pgo_connection:configure(Pid, PoolConfig)
end || _ <- lists:seq(1, Size)],
Relies on if messages can be filtered by format_status and setting the processes that handle the PoolConfig to sensitive so if any of them crash they won't show the password.
The latter part is the most annoying. It will hamper debugging if the processes we pass the config around to have to be set to sensitive.
Wait, nevermind, (2) is not an issue, phew, password is already not stored in there.
Note: pgo_type_server also has PoolConfig so it needs to be filtering the password out from the data in a format_status.
You could store the password in an anonymous function perhaps? Then the function would be printed instead
Clever, I like it!
Heh, well I'll be, it is even the first bullet in https://security.erlef.org/secure_coding_and_deployment_hardening/sensitive_data.html :)