Safeguard
Compliance•

pgAudit session vs object logging: what to log in PostgreSQL

pgAudit adds detailed audit logs to PostgreSQL. Compare session and object logging, pick log classes and avoid writing secrets into your audit trail.

Safeguard Security Team
3 min read

pgAudit gives PostgreSQL detailed audit logging through the standard log. Session logging records whole categories of statements, such as writes or role changes. Object logging records reads and writes on chosen tables only. Use session logging for broad coverage of privileged activity and object logging for a few sensitive tables.

What it is

The project describes pgAudit as detailed session and object audit logging through PostgreSQL's standard logging facility. It is an extension, so you load it and then decide what to record. Auditors tend to ask who changed what and who read sensitive data, and the stock logs rarely answer that cleanly. If you only need to see slow queries or connection failures, the built in settings are enough, see PostgreSQL log settings that help security.

Setup basics

From the README:

  • pgAudit must be in shared_preload_libraries. Without that, an error is raised at load time and no audit logging occurs.
  • Run CREATE EXTENSION pgaudit before setting pgaudit.log. It installs event triggers that add object type and name to DDL entries. Without it, logging still works but DDL entries lack that detail.

Session logging

Session logging records statements executed in the backend, filtered by the pgaudit.log setting. The classes are:

  • READ: SELECT and COPY from a relation or query
  • WRITE: INSERT, UPDATE, DELETE, TRUNCATE and COPY into a relation
  • ROLE: GRANT, REVOKE and role creation or changes
  • DDL: schema changes not in ROLE
  • MISC: commands such as DISCARD, FETCH, CHECKPOINT, VACUUM and SET
  • ALL: every class, and you can subtract with a minus sign, for example all, -misc

The default is none. A sensible starting point for many teams is ROLE and DDL, because they are low volume and high value. Adding READ and WRITE everywhere can flood storage.

Object logging

Object logging records SELECT, INSERT, UPDATE and DELETE on specific relations. TRUNCATE is not included. You set pgaudit.role to a master audit role, then grant that role permissions on the tables you care about. Anything the audit role could do on those tables gets logged. The README presents it as a finer alternative to logging read and write for everything.

Do not log secrets into the audit trail

The README's own examples show an UPDATE that sets a password in plain text, which would land in the log. Parameter logging is off by default through pgaudit.log_parameter; if you turn it on, values passed to statements are written as well. A size cap exists in pgaudit.log_parameter_max_size. Decide who can read these logs and how long they are kept, and encrypt the log store.

Limits to state honestly

The README says audit logging is best effort and not transactional, so a crash or a full log volume can leave committed work without entries. It also says superuser activity cannot be reliably audited. If you rely on this for compliance, say so in your control description instead of promising completeness.

Try it yourself

Click through it at your own pace, or open it full screen.

Pick a framework control and see how one piece of evidence, such as a database audit log export, can map to more than one requirement.

Quick check

Is the default pgaudit.log setting useful out of the box?

No. The default is none, so nothing is audited until you choose classes or set up object logging.

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.