Security model¶
The claim¶
No role, including superuser, can perform an operation a vault table's
permissionsset does not grant. NoGRANT,SET ROLE,ALTER TABLE, or access-method change widens it. Enforcement fails closed: where the extension's state cannot be established, every operation is denied.
Why superuser is not an exception¶
The enforcement callbacks are not role-aware. There is no privilege check to bypass — a superuser's INSERT reaches tuple_insert exactly as anyone else's does, and the same comparison against the same bitmask decides it.
Enforcement sits below PostgreSQL's ACL system, so a GRANT cannot widen what the access method allows. The most a broader grant achieves is letting more roles attempt something that is still refused.
The test suite covers every ungranted operation attempted as the table owner, as a role holding every SQL privilege PostgreSQL can grant, and as a superuser. All refused.
Fail-closed as a design rule¶
Where the extension cannot establish what a table permits, the answer is deny.
- Options that cannot be parsed produce an empty permission set.
- A null retention deadline is treated as not expired.
- A missing catalogue row grants nothing.
The library refuses to load on demand¶
pg_am.amhandler carries a probin pointing at this library, so a backend that has not preloaded it would still load it the moment it opened a vault table. That covers most operations but not all of them, which is why it is not relied on.
UPDATE, DELETE, DROP and SET ACCESS METHOD open the relation through the access method first, so an on-demand load installs the hooks in time. TRUNCATE and a catalogue-only ALTER TABLE reach their enforcement point before the relation is ever opened that way. On a server missing the setting, those two would proceed unchecked: a table granting nothing could be emptied and its definition changed, while everything else stayed protected.
Refusing on-demand initialisation replaces that selective exposure with a uniform one. A server without the setting cannot open a vault table at all — not even to read it — so a configuration missing the library freezes the data rather than partly exposing it.
The boundary¶
This is enforcement inside the database. It does not constrain someone with operating-system access to the data directory, and no in-database mechanism could: PostgreSQL grants superusers shell-equivalent access via COPY ... FROM PROGRAM and untrusted procedural languages.
That is the universal precondition of every database control — foreign keys, row level security, ACLs, encryption at rest — and none of them carry the caveat either. Compliance deployments constrain superuser at the role and operating-system layer; this extension guarantees that nothing beneath that line can be silently altered.
What it does contribute even against a determined administrator is that tampering cannot be silent. Removing the library needs a configuration change and a restart; replacing it changes a file on disk. Both are visible to file-integrity monitoring and configuration drift detection.
What is not protected¶
- Reading. This extension has nothing to do with
SELECT. Ordinary permissions apply. - Confidentiality of the declaration. A table's permissions and retention live in
pg_class, which PostgreSQL makes world-readable. - The data files themselves. Use filesystem permissions and encryption at rest as you would anyway.