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 who can run arbitrary code as the server, and no in-database mechanism could: PostgreSQL grants superusers shell-equivalent access via COPY ... FROM PROGRAM and untrusted procedural languages, so a superuser can write a shared library and load it.
A vault table's definition is also verified independently of any statement. What defines it — its declaration, its storage and its columns — is checked for integrity within every transaction that could affect it, and a transaction that would leave any of them altered is refused. Catalogue rows belonging to anything else are unaffected, so ordinary DBA work on other objects is untouched.
What remains is the code-execution boundary. 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.
The cost of crossing it is the point. Writing and installing a shared library, or a configuration change plus a restart, is a great deal more work than one UPDATE — and far more visible. 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, and because the library refuses to load outside shared_preload_libraries, removing it leaves every vault table unreadable rather than quietly unprotected.
So tampering cannot be silent, which is the property a compliance deployment actually depends on.
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.