Anonymize PostgreSQL and subset it into safe staging databases in seconds.
Subveil is a free Go CLI for PostgreSQL data masking and database subsetting. It copies a small, referentially intact slice of production and masks PII in flight, so your local environments and CI/CD pipelines stay compliant.
$ subveil --help- Raw rows never leave your network
- Works in CI and PR previews
- Audit receipt for every run
See it work
Real data in. Safe data out.
Subveil copies a slice of your production database and swaps anything personal for realistic fakes. Your app and tests keep working, and no real customer data is exposed.
Your production database
Real customer dataJohn Doe
customer #1+1 415 555 0134
Priya Nair
customer #2+91 98765 43210
Maya Chen
customer #3+1 206 555 0188
Your staging copy
Safe to shareLena Hartmann
customer #1+1 555 0119
Ines Baptiste
customer #2+1 555 0115
Owen Quill
customer #3+1 555 0131
Sample data, simplified for illustration. Customer numbers stay the same on both sides.
Personal details are replaced
Names, emails and phone numbers become realistic fakes.
Everything else stays the same
IDs, dates, amounts and relationships between tables are untouched, so your app and tests behave as in production.
Consistent every time
The same person always gets the same fake, in every table and every refresh.
How it works
Three commands from production to a safe staging copy
- 01
Introspect
Reads your catalog, finds foreign keys and flags columns that look like PII. Writes subveil.yaml for you to review.
$ subveil init
introspected 64 tables · 112 foreign keys
- 02
Preview
Shows the load order, detects circular references and lists what will be masked. Writes nothing.
$ subveil plan
level 0 → 3 · 2 cycles · 17 masked columns
- 03
Copy, masked
Streams a referentially intact slice into your target in one transaction, masking each value in flight.
$ subveil pull
complete 142,330 rows · raw PII leaked: 0
Why Subveil?
Real data shape. None of the real data.
Graph-aware subsetting
Subveil reads your foreign keys, topologically sorts the tables and pulls exactly the rows each slice needs. Circular and self-referential dependencies are resolved automatically—no dangling references, no failed restores.
Deterministic HMAC anonymization
The same input always maps to the same fake output—across tables and microservices.
Zero-trust architecture
Runs entirely on your machine or inside your GitHub Actions. Your raw PII never touches our cloud—there is nothing to breach.
SOC 2 & HIPAA ready
Every sync emits a cryptographic audit receipt proving which columns were masked and that zero raw PII left production—ready to hand to your auditor.
{
"run": "sync_01J9ZK4Q",
"env": "pr-preview",
"masked_columns": 17,
"raw_pii_exported": 0,
"receipt": "sha256:9f2c…b71e"
}Compare
The old way vs. the Subveil way
| Capability | The old wayManual SQL seed scripts | The old wayRaw production dumps | The Subveil waypull → mask → ship |
|---|---|---|---|
| Production-like data shape | Hand-written, drifts from prod | Exact copy | Statistically faithful slice |
| PII stays out of staging | Fake by default | Full PII exposed | Masked in-flight |
| Foreign keys stay valid | Breaks on every migration | All rows included | Graph-aware, cycles handled |
| Time to a fresh environment | Hours of maintenance | Hours to restore terabytes | Seconds, 5% of the size |
| Same user across services | Inconsistent IDs | Identical (unsafe) | Deterministic HMAC |
| Audit evidence | None | A compliance finding | Cryptographic receipts |
Zero-trust by design
Built so security can say yes
Rows never leave your network
The CLI runs in your VPC or CI runner. Subveil Cloud only receives metadata and hashed receipts.
Production is read-only
Every pull reads one REPEATABLE READ, read-only snapshot, so the source can never be changed.
Every run leaves a receipt
Hashes of the policy and hosts, row counts and masked columns. Never values. Ready for your auditor.
FAQ
Questions your security team will ask
Does Subveil ever see my production data?
No. The CLI runs inside your network or CI runner and connects to your databases directly. Subveil Cloud stores metadata only: table and column names, policies and audit receipts. Row values are never sent.
Will foreign keys and joins still work after masking?
Yes. Subveil walks your foreign-key graph, loads parents before children and leaves keys untouched. Masking is deterministic, so the same input maps to the same fake everywhere, and joins on masked columns still line up.
What happens with circular or self-referential foreign keys?
Subveil detects each cycle during `subveil plan` and resolves it in two passes (for example, loading with a nullable edge set to NULL, then back-filling it), so the restore never fails on a constraint.
Can I use it in CI for pull-request databases?
Yes. Run the CLI in GitHub Actions to refresh staging or spin up an expiring database per pull request. The Branches page generates the workflow file for you.
How does the audit trail work?
After every pull the CLI submits a receipt with hashes of the policy, source and target, row counts and masked column names. Receipts help you evidence your controls; they don't by themselves make you SOC 2 or HIPAA compliant.
What does it cost?
The CLI is free to use. The Community plan is free forever and includes one cloud project. Team (from ** a month) adds central policy sync, drift alerts and a longer audit ledger, and Enterprise (from ** a month) adds compliance controls. Paid plans open soon. See pricing for details.
More in the docs or on the security page.