Anonymize a Postgres database for staging and CI

Teams need realistic staging and CI data, but copying production Postgres means copying real PII. PrivaCI solves this anonymize postgres database for staging: it produces a masked clone that keeps foreign keys and value distributions intact, so tests behave like production without exposing customer data.

Why not pg_dump and a few UPDATE scripts?

Hand-rolled scripts drift from the schema, break referential integrity, and rarely scale to multi-GB tables. PrivaCI streams with bounded memory, auto-detects PII columns, masks deterministically, and records an audit log of what changed.

The workflow

  1. Point PrivaCI at a source database and a target.
  2. Default (schema_mode: replicate): clone schema into an empty target, then stream masked rows. For a long-lived staging database you already migrate, set schema_mode: assume_existing (often with on_existing_data: truncate) so PrivaCI validates the prebuilt schema and loads into it — see configuration.
  3. Hand the target to staging/CI — safe to share, FK-consistent.
docker run --rm ghcr.io/boundarylogic/privaci:latest --help

See the quickstart for the full procedure, or read the source on GitHub.

Related guides

This page covers a long-lived shared staging refresh (typically full-database). For an ephemeral masked database per pull request, see production-shaped Postgres test databases in CI. For a one-off tenant repro from DR standby, see support repro.