Skip to main content

Bauta

Put a mask on production: a safe, realistic stand-in for your production data, in whichever database you need it. Bauta masks what it copies, copies only the slice you need with every relationship intact, generates what may not be copied at all, and moves data between databases on a schedule you already run, with nothing to host.

  • Masking: consistent across tables and runs, one-to-one for keys (NIST FF1 where policy requires it), applied before anything reaches the target, and every column must be covered.
  • Discovery, subsets and synthetic data: propose a masking policy from a live schema, copy a referentially complete slice of production, create the copy's tables in whichever database it goes to, and fill tables that can't be copied with generated rows.
  • Audit: report what every job does with data and what a reviewer should question, and seal each run's masking manifest so it can be verified later.
  • Six databases: Oracle, SQL Server, PostgreSQL, MySQL, MariaDB and SQLite, as source or target in any combination.
  • Streaming: memory stays flat however large the table, and PostgreSQL and SQL Server targets load in bulk.
  • Fast: ten million rows of six masked columns in under two minutes on one core with the optional native masker, and under eight without. Either way the masks are the same.
  • Incremental loads: extract only what changed since the last successful run.
  • A dependency graph: jobs run in order, concurrently where they can, each in its own process with an optional timeout.
  • Operable: run history, Prometheus metrics, webhook alerts, run state in a file or a table, and passwords from a command for cloud IAM tokens.
  • No infrastructure: a pip install, some YAML, and a command you run from cron.

Install

Python 3.10 or newer. Choose the drivers you need as extras; each is loaded only when a connection uses it.

pip install "bauta[postgresql,oracle]"

It isn't on PyPI yet. Until the first release, install from a clone:

git clone https://github.com/ribeiro11075/bauta.git
cd bauta
pip install -e ".[postgresql,oracle]"
Extra Driver Needs besides pip
mysql, mariadb mysql-connector-python nothing
postgresql psycopg2, built from source a C compiler and PostgreSQL's client library (below)
oracle oracledb, in thin mode nothing — no Oracle client
mssql pymssql nothing
sqlite Python's own sqlite3 nothing
fpe cryptography, for the fpe masking strategy nothing; oracle already brings it
all every driver above as for postgresql

Building psycopg2. pip compiles it, so it needs a compiler and pg_config:

  • macOS: xcode-select --install, then brew install libpq and export PATH="$(brew --prefix libpq)/bin:$PATH" (Homebrew doesn't put libpq on the path by itself).
  • Debian or Ubuntu: apt install build-essential libpq-dev.

To skip the build, leave postgresql (and all) out and install the prebuilt driver beside the other extras: pip install "bauta[mysql,oracle,mssql]" psycopg2-binary. psycopg2's maintainers recommend the source build for production.

The native masker (optional). bauta-rs, in mask-rs/, masks in Rust: four to five times the throughput, identical masks, nothing to configure. With Rust 1.83 or newer, pip builds it in the same command as the rest:

pip install -e ".[all]" ./mask-rs/py

Without Rust, leave ./mask-rs/py off; everything works, only slower. See the native masker.

Quickstart

mkdir configuration
cp example/starter/configuration/*.yaml configuration/

Edit configuration/database.yaml and configuration/jobs.yaml for your databases, then supply the credentials they reference:

export SOURCE_DB_PASSWORD=...  TARGET_DB_PASSWORD=...  MASKING_KEY=...

bauta validate          # check the configuration, offline
bauta run --dry-run     # check connections and tables, moving nothing
bauta run               # run every job once

To see it work without any of that, using throwaway SQLite databases:

python example/walkthrough/demo.py       # the whole workflow: discover, subset, audit, mask, verify, synthesize
python example/incremental/demo.py       # streaming and incremental loads
python example/masking/demo.py           # masking, discovery and a subset, from Python
python example/native-masking/demo.py    # the same job masked in Python and in Rust, compared

The command

bauta run              run data jobs once, masking any with a `masking` section
bauta validate         check configuration without connecting
bauta jobs             show the job graph and what's due
bauta history          show recent job outcomes recorded with --history

bauta discover         propose a masking policy for tables
bauta subset           generate jobs that copy a referentially complete subset
bauta schema           create target tables from source ones, in the target's dialect
bauta synthesize       fill tables with generated rows, for data that can't be copied
bauta clear            empty the target tables of jobs, children first

bauta audit            report what each job does with data, and what to question
bauta verify-manifest  check a manifest is unaltered, and who signed it
Exit code Meaning
0 every job completed
1 a job failed, or was skipped because a predecessor failed, or the command failed on a database error
2 invalid configuration or usage
130 interrupted by a signal: running jobs finished, the rest were skipped

run makes one pass and exits, so it fits under cron or a Kubernetes CronJob. A second run sharing the same run state refuses to start while the first is still going. The useful flags:

Flag
--config DIR where the YAML lives; default ./configuration
--job NAME run only this job — without its predecessors, which it warns about
--force ignore refresh windows
--forever stay running; for freshness under a minute
--log-format json structured logs for a collector
--log FILE also log to a file, in addition to stderr (--quiet silences stderr)
--memory FILE where run state (last runs, watermarks) is kept, overriding jobs.yaml's memory
--memory-database ALIAS keep run state in a database table instead
--history FILE append each job's outcome to a JSON-lines history
--metrics FILE write Prometheus metrics for the textfile collector (--metrics-push URL for a Pushgateway)
--notify-url URL post to a webhook when a run doesn't succeed; default $BAUTA_NOTIFY_URL
--accept-key-change run upsert jobs whose masking key changed since their last run
--manifest FILE write a sealed JSON record of what was masked, and how; signed if $BAUTA_MANIFEST_KEY is set

Documentation

Configuration every field, how credentials are read from the environment, and connection options such as TLS
Masking strategies, consistent masks across tables, the key, the manifest, audit, discover, subset, schema, synthesize and clear
How it works streaming, incremental loads, retries, scheduling, and the masking design
Operating it run state, history, metrics and notifications
Security model what masking protects and what it doesn't, the constructions, keys, and a deployment checklist
Library embedding it in Python, results, memory backends
Development running the tests, including against real databases

Layout

bauta/ the package; runner.py runs jobs, masking.py masks, databaseDialects.py holds per-database SQL
mask-rs/ the optional native masker, in Rust — see its README
example/ runnable demos, each with its configuration/, and a starter configuration — see its README
docs/ the documentation above
tests/ the test suite

License

MIT

Release files for bauta 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bauta 0.1.0
File Size Uploaded
bauta-0.1.0.tar.gz 235.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bauta 0.1.0
File Interpreter ABI Platform
bauta-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 360.3 kB

Release files / bauta-0.1.0.tar.gz

Download URL bauta-0.1.0.tar.gz
Size 235.4 kB
Tags Source
SHA-256 checksum
How to use checksums
8f7d347e1d3366a140aa321557b5bb4a2a05c52d8aeb95bf667236093b9ea899
BLAKE2b-256 checksum
How to use checksums
069a73932ae7e5983d55292660bb1c384f572c2e348cd1abc4538ac4e309b568
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release files / bauta-0.1.0-py3-none-any.whl

Download URL bauta-0.1.0-py3-none-any.whl
Size 124.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
57ec9798af28b5affd21a96faf5d00f26a28c620afb9a2d1df42a50052f7588c
BLAKE2b-256 checksum
How to use checksums
96cf4a9636485bdbf816af7ee3e65aace547527e4b2c4a220ddfbda87b4b4759
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page