Safeguard
Security Guides•

PostgreSQL logging for security without leaking passwords

Which PostgreSQL log settings help security reviews, and why log_statement = all can write plaintext passwords into your logs.

Safeguard Security Team
3 min read

For security visibility in PostgreSQL, log connections and disconnections, log DDL, and log slow statements, but avoid log_statement = 'all'. The manual warns that logged statements might reveal sensitive data and even contain plaintext passwords. Lock down log file access as well.

Connection logging

log_connections is empty by default, meaning no connection logging. In current versions it takes a list: receipt, authentication, authorization, setup_durations, or all. The common values on, true, yes and 1 enable receipt, authentication and authorization. Failed authentication is always logged.

log_disconnections defaults to off. Turning it on records the session duration, which helps when you are reconstructing who was connected during an incident. Both settings can only be changed at session start and need superuser or the right SET privilege.

Statement logging

log_statement defaults to none. The values are:

  • ddl for CREATE, ALTER and DROP.
  • mod for DDL plus INSERT, UPDATE, DELETE, TRUNCATE and COPY FROM.
  • all for everything.

DDL logging is a sensible security baseline because it records schema and permission changes. Be aware of a limit the manual states: statements with simple syntax errors are not logged even under all, and under the extended protocol, statements that fail before execution are also missed unless you set log_min_error_statement to ERROR or lower.

Why not "all"

Statements such as creating a role with a password can put the password into the log. The manual's wording is that logged statements "might reveal sensitive data and even contain plaintext passwords." Bind parameter values are included too. Related settings help: log_parameter_max_length trims logged parameter values, and log_parameter_max_length_on_error controls whether parameters appear in error messages (default off).

Slow statement logging

log_min_duration_statement is disabled at -1. Setting it to something like 250ms logs statements that take at least that long. It is aimed at performance, but unusual slow queries from an unexpected user can also be a lead during an investigation.

Make the log useful

Set log_line_prefix to include who and where. The default is just a timestamp and process ID. A prefix like this adds user, database and application:

log_line_prefix = '%m [%p] %q%u@%d/%a '

Protect the log itself

log_file_mode defaults to 0600, which limits the file to the server owner. The manual advises against world-readable logs. For group access it suggests moving log_directory outside the data directory. Ship logs to a central store with its own access controls, and set retention deliberately.

Logging tells you what happened. It does not prevent it. Pair it with tight roles, as in least privilege with predefined roles.

Quick check

Is log_statement = 'ddl' enough for audits?

It covers schema and permission changes but not data reads or writes. Use mod if you need data changes, and weigh that against the sensitive data it can capture.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.