Skip to content

add audit_log table and structured COPY event logging (v0.1.5)#10

Merged
rustwizard merged 5 commits into
masterfrom
audit-log
Mar 27, 2026
Merged

add audit_log table and structured COPY event logging (v0.1.5)#10
rustwizard merged 5 commits into
masterfrom
audit-log

Conversation

@rustwizard

Copy link
Copy Markdown
Owner
  • Create block_copy_command schema and audit_log table in hooks.sql
  • Add migration script block_copy_command--0.1.4--0.1.5.sql
  • Add GUC block_copy_command.audit_log_enabled (default on)
  • Write every intercepted COPY to audit_log via SPI (PgTryBuilder swallows errors so a missing table never breaks blocking logic)
  • Capture both session_user and current_user to handle SET ROLE
  • Derive block_reason: role_listed | program_blocked | direction_blocked
  • Improve server log format to include direction, program flag, and reason
  • Note: blocked events are rolled back with the aborted transaction; server log remains authoritative for blocked attempts

- Create block_copy_command schema and audit_log table in hooks.sql
- Add migration script block_copy_command--0.1.4--0.1.5.sql
- Add GUC block_copy_command.audit_log_enabled (default on)
- Write every intercepted COPY to audit_log via SPI (PgTryBuilder
  swallows errors so a missing table never breaks blocking logic)
- Capture both session_user and current_user to handle SET ROLE
- Derive block_reason: role_listed | program_blocked | direction_blocked
- Improve server log format to include direction, program flag, and reason
- Note: blocked events are rolled back with the aborted transaction;
  server log remains authoritative for blocked attempts
@rustwizard rustwizard self-assigned this Mar 27, 2026
pgrx unit tests (lib.rs):
- Replace untestable SPI-COPY test with two structural tests:
  test_audit_log_expected_columns_exist — checks all 11 columns are present
  test_audit_log_is_writable — direct INSERT verifies schema is correct

docker/test.sh (tests 16-23):
- 16: superuser COPY TO creates a row in audit_log
- 17: row has correct content (direction=TO, is_program=f, blocked=f, reason=NULL)
- 18: current_user_name recorded as 'postgres'
- 19: COPY FROM STDIN creates a row with direction=FROM
- 20: copy_is_program=true recorded when COPY TO PROGRAM (block_program=off)
- 21: audit_log_enabled=off suppresses writes entirely
- 22: blocked COPY leaves no row in audit_log (tx rollback — server log is authoritative)
- 23: both session_user_name and current_user_name are populated
PostgreSQL casts boolean columns to 'true'/'false' when used in || string
concatenation, not 't'/'f'. Tests 17 and 19 expected 'f' but received 'false'.
Test 23 used ::text cast on a boolean expression which also yields 'true'/'false'
instead of the 't'/'f' that psql renders for raw boolean columns; fixed by
removing the explicit cast so psql formats the value.
Add full reference for block_copy_command.audit_log (columns, indexes,
access control) and the audit_log_enabled GUC. Include example queries
for time-range scans, blocked-only events, and per-user summaries.
Update the Docker test coverage list to reflect the audit log tests
added in v0.1.5.
@rustwizard rustwizard merged commit 15a6874 into master Mar 27, 2026
1 check passed
@rustwizard rustwizard deleted the audit-log branch March 27, 2026 12:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant