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 pgauditbefore settingpgaudit.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.