Append-only event log — Examples
Append-only event log
Section titled “Append-only event log”An audit or event table should only ever grow: rows are inserted, never changed
or removed. One policy with a multi-command for clause locks
both UPDATE and DELETE for the application role.
enum EventKind { Created, Updated, Deleted }
type Event { required topic: str; required kind: EventKind; payload: json; required actor: str; required at: datetime { default := now() };
# A DELETE has no "new row" to check, so block both writes with `using (false)` # — no existing row is ever visible to UPDATE or DELETE. policy append_only for update, delete using ( false );}Because Postgres allows one command per CREATE POLICY, the for update, delete
list expands to two policies (suffixed to keep their names unique):
ALTER TABLE "event" ENABLE ROW LEVEL SECURITY;CREATE POLICY "append_only_update" ON "event" FOR UPDATE USING (false);CREATE POLICY "append_only_delete" ON "event" FOR DELETE USING (false);Inserts still work; updates and deletes from the app role affect zero rows.
insert Event { topic := $topic, kind := EventKind.Created, actor := $actor };