anon
Overview
| Package | Version | Category | License | Language |
|---|---|---|---|---|
pg_anon | 3.0.1 | SEC | PostgreSQL | Rust |
| ID | Extension | Bin | Lib | Load | Create | Trust | Reloc | Schema |
|---|---|---|---|---|---|---|---|---|
| 7050 | anon | No | Yes | Yes | Yes | No | No | anon |
| Related | faker pgsodium pgcrypto pgaudit set_user pg_tde |
|---|
Version
| Type | Repo | Version | PG Ver | Package | Deps |
|---|---|---|---|---|---|
| EXT | PIGSTY | 3.0.1 | 1817161514 | pg_anon | - |
| RPM | PIGSTY | 3.0.1 | 1817161514 | pg_anon_$v | - |
| DEB | PIGSTY | 3.0.1 | 1817161514 | postgresql-$v-pg-anon | - |
Build
You can build the RPM / DEB packages for pg_anon using pig build:
pig build pkg pg_anon # build RPM / DEB packages
Install
You can install pg_anon directly. First, make sure the PGDG and PIGSTY repositories are added and enabled:
pig repo add pgsql -u # Add repo and update cache
Install the extension using pig or apt/yum/dnf:
pig install pg_anon; # Install for current active PG version
pig ext install -y pg_anon -v 18 # PG 18
pig ext install -y pg_anon -v 17 # PG 17
pig ext install -y pg_anon -v 16 # PG 16
pig ext install -y pg_anon -v 15 # PG 15
pig ext install -y pg_anon -v 14 # PG 14
dnf install -y pg_anon_18 # PG 18
dnf install -y pg_anon_17 # PG 17
dnf install -y pg_anon_16 # PG 16
dnf install -y pg_anon_15 # PG 15
dnf install -y pg_anon_14 # PG 14
apt install -y postgresql-18-pg-anon # PG 18
apt install -y postgresql-17-pg-anon # PG 17
apt install -y postgresql-16-pg-anon # PG 16
apt install -y postgresql-15-pg-anon # PG 15
apt install -y postgresql-14-pg-anon # PG 14
Preload:
shared_preload_libraries = 'anon';
Create Extension:
CREATE EXTENSION anon;
Usage
postgresql_anonymizer (extension name: anon) masks or replaces personally identifiable information (PII) using a declarative approach. Masking rules are defined directly in the database schema using security labels.
CREATE EXTENSION IF NOT EXISTS anon CASCADE;
SELECT anon.init();
Declaring Masking Rules
SECURITY LABEL FOR anon ON COLUMN player.name
IS 'MASKED WITH FUNCTION anon.fake_last_name()';
SECURITY LABEL FOR anon ON COLUMN player.id
IS 'MASKED WITH VALUE NULL';
Static Masking
Permanently replace PII in the database:
SECURITY LABEL FOR anon ON COLUMN customer.full_name
IS 'MASKED WITH FUNCTION anon.fake_first_name() || '' '' || anon.fake_last_name()';
SECURITY LABEL FOR anon ON COLUMN customer.birth
IS 'MASKED WITH FUNCTION anon.random_date_between(''1920-01-01''::DATE, now())';
SELECT anon.anonymize_database();
-- Also available: anon.anonymize_table(), anon.anonymize_column()
Dynamic Masking
Hide PII from specific roles while others see original data:
SELECT anon.start_dynamic_masking();
CREATE ROLE skynet LOGIN;
SECURITY LABEL FOR anon ON ROLE skynet IS 'MASKED';
SECURITY LABEL FOR anon ON COLUMN people.lastname
IS 'MASKED WITH FUNCTION anon.fake_last_name()';
SECURITY LABEL FOR anon ON COLUMN people.phone
IS 'MASKED WITH FUNCTION anon.partial(phone, 2, $$******$$, 2)';
When skynet queries the table, masked data is returned automatically.
Anonymous Dumps
pg_dump_anon.sh -h localhost -p 5432 -U bob bob_db > dump.sql
Common Masking Functions
| Function | Description |
|---|---|
anon.fake_first_name() | Random first name |
anon.fake_last_name() | Random last name |
anon.fake_company() | Random company name |
anon.random_date_between(d1, d2) | Random date in range |
anon.random_zip() | Random zip code |
anon.partial(value, prefix, padding, suffix) | Partial scrambling |
anon.random_string(n) | Random string of length n |
anon.random_int_between(i1, i2) | Random integer in range |
Feedback
Was this page helpful?
Thanks for the feedback! Please let us know how we can improve.
Sorry to hear that. Please let us know how we can improve.