AUDIT ACCESS records every read or write against a table, view, or database so you can trace who touched what data and when.
AUDIT ACCESS instructs ParadeDB (a PostgreSQL-compatible engine) to log every successful SELECT, INSERT, UPDATE, DELETE, and TRUNCATE executed on the chosen object. Each event is written to the server log or an audit table, capturing username, time, source IP, and the executed SQL.
Activate it when regulations (HIPAA, SOC2, GDPR) require a full data-access trail, or when investigating suspicious changes to sensitive entities like Customers or Orders.
Create a reusable policy with CREATE AUDIT POLICY, specify the actions, then attach the policy with AUDIT POLICY. This keeps DDL tidy and lets you reuse the same rules on multiple tables.
CREATE AUDIT POLICY customer_rw
ACTIONS SELECT, INSERT, UPDATE, DELETE;
The policy now exists but is not yet attached to any table.
AUDIT POLICY customer_rw ON TABLE Customers;
From this point forward every query touching Customers is captured.
Yes—use ON DATABASE current_database(), but do so sparingly because logging volume explodes.
If ParadeDB is configured with pgaudit.log_to_table = on, query pgaudit.log_entries. Otherwise inspect the PostgreSQL log directory.
SELECT log_time,
username,
statement
FROM pgaudit.log_entries
WHERE object_name = 'Customers'
ORDER BY log_time DESC
LIMIT 20;
NOAUDIT POLICY customer_rw ON TABLE Customers;
Remove the policy entirely with DROP AUDIT POLICY customer_rw; when you no longer need it.
Forgetting to EXCLUDE bulk ETL users. Large nightly loads flood audit tables. Add EXCEPT role etl_user
to the policy.
Auditing entire databases in production. This degrades performance. Audit the smallest reasonable scope—ideally a single table or schema.
Yes, minimally for low-traffic tables, but significantly for high-frequency writes. Benchmark before enabling in a busy path.
No. It ships with ParadeDB or with the pgAudit extension patched to support SQL-level policies.
Yes, if you add the keyword ERROR to the ACTIONS list or enable pgaudit.log = 'read, write, ddl, role, misc'.
Yes. Use a WHEN clause such as WHEN (extract(hour from current_timestamp) BETWEEN 8 AND 18).