audit_log immutability is enforced by triggers rejecting UPDATE/DELETE/TRUNCATE (crates/db/migrations/0001_audit_log.sql). Triggers are robust against the application's normal DML, but a table owner / superuser can bypass them via DDL — ALTER TABLE audit_log DISABLE TRIGGER, DROP TRIGGER, or SET session_replication_role = replica.
To make the append-only guarantee hold even if the app connection is compromised, the application's runtime DB role should be a non-owner with only INSERT and SELECT on audit_log (and appropriate grants elsewhere) — so it cannot disable or drop the triggers. Fits naturally into the per-org provisioning model (a migration/owner role separate from the app role).
Define an app role distinct from the migration/owner role.
Grant the app role INSERT, SELECT on audit_log (no UPDATE/DELETE/TRUNCATE, not owner).
Document/automate this in provisioning.
Source: Plan 1 (audit spine) final review — non-blocking, security hardening.
`audit_log` immutability is enforced by triggers rejecting UPDATE/DELETE/TRUNCATE (`crates/db/migrations/0001_audit_log.sql`). Triggers are robust against the application's normal DML, but a **table owner / superuser can bypass them** via DDL — `ALTER TABLE audit_log DISABLE TRIGGER`, `DROP TRIGGER`, or `SET session_replication_role = replica`.
To make the append-only guarantee hold even if the app connection is compromised, the application's runtime DB role should be a **non-owner with only `INSERT` and `SELECT`** on `audit_log` (and appropriate grants elsewhere) — so it cannot disable or drop the triggers. Fits naturally into the per-org provisioning model (a migration/owner role separate from the app role).
- [ ] Define an app role distinct from the migration/owner role.
- [ ] Grant the app role `INSERT, SELECT` on `audit_log` (no `UPDATE`/`DELETE`/`TRUNCATE`, not owner).
- [ ] Document/automate this in provisioning.
_Source: Plan 1 (audit spine) final review — non-blocking, security hardening._
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
audit_logimmutability is enforced by triggers rejecting UPDATE/DELETE/TRUNCATE (crates/db/migrations/0001_audit_log.sql). Triggers are robust against the application's normal DML, but a table owner / superuser can bypass them via DDL —ALTER TABLE audit_log DISABLE TRIGGER,DROP TRIGGER, orSET session_replication_role = replica.To make the append-only guarantee hold even if the app connection is compromised, the application's runtime DB role should be a non-owner with only
INSERTandSELECTonaudit_log(and appropriate grants elsewhere) — so it cannot disable or drop the triggers. Fits naturally into the per-org provisioning model (a migration/owner role separate from the app role).INSERT, SELECTonaudit_log(noUPDATE/DELETE/TRUNCATE, not owner).Source: Plan 1 (audit spine) final review — non-blocking, security hardening.