Skip to content

Installation

Three steps: build it, enable it, create it.


1. Build and install the files

export PG_CONFIG=/usr/lib/postgresql/18/bin/pg_config   # Debian, Ubuntu
export PG_CONFIG=/usr/pgsql-18/bin/pg_config            # Rocky, RHEL, Fedora

make
sudo make install

Build dependencies

You need the PostgreSQL development package, plus the OpenSSL and Kerberos development headers:

sudo apt-get install postgresql-server-dev-18 libssl-dev libkrb5-dev   # Debian, Ubuntu
sudo dnf install postgresql18-devel openssl-devel krb5-devel           # Rocky, RHEL, Fedora

The OpenSSL and Kerberos headers are needed because the extension reads the client address for its violation records, and the PostgreSQL header that exposes it pulls in whatever the server was built with. Distribution packages are built with both.

This one catches people out

A PostgreSQL you built yourself without SSL or GSSAPI does not need those headers, so the build succeeds on your workstation and then fails on a packaged server. If you see openssl/ssl.h: No such file or directory or gssapi/gssapi.h: No such file or directory, install the two packages above.


2. Enable it and restart

In postgresql.conf:

shared_preload_libraries = 'pg_vault_tables'

Then restart PostgreSQL. A reload is not enough — this setting is only read at startup.

If something else is already listed, add to it:

shared_preload_libraries = 'pg_stat_statements,pg_vault_tables'

3. Create the extension

In each database that needs it:

CREATE EXTENSION pg_vault_tables;

This creates the vault access method and the pgvault_tables schema.


Check it worked

SELECT amname FROM pg_am WHERE amname = 'vault';
SELECT * FROM pgvault_tables.view_vault_tables();

The first should return one row. The second should return none, since you have not created any vault tables yet.


Why the preload step is not optional

The extension refuses to load any other way. If you skip it, CREATE EXTENSION fails immediately:

ERROR:  pg_vault_tables must be loaded via shared_preload_libraries

That is deliberate. Loading on demand would leave a gap: on a server started without the setting, TRUNCATE and ALTER TABLE reach the point where they would be refused before anything has opened the table and triggered the load, so those two commands would go through while everything else stayed protected.

Refusing to load any other way closes that gap. A server without the setting cannot open a vault table at all, so removing the library from the configuration freezes the data instead of partly exposing it, and the failure is loud and immediate rather than quiet and selective.

The practical consequence: every server that touches these tables needs the setting, including every standby. See Replication and Standbys.


Where things are installed

File Location
pg_vault_tables.so $(pg_config --pkglibdir)
pg_vault_tables.control $(pg_config --sharedir)/extension
pg_vault_tables--0.1.sql $(pg_config --sharedir)/extension