PrivaCI CLI Reference¶
The privaci executable is the single entry point for every operation. This
page documents each subcommand, its options, and copy-pasteable examples. For
the mask-rules.yaml format see configuration.md; for
exit codes see error-codes.md.
Running
privaciwith no subcommand is identical toprivaci run.
Command summary¶
| Command | Purpose |
|---|---|
run |
Execute a masking run against source → target |
dry-run |
Pre-flight checks and a per-table plan; no writes |
resume |
Continue an interrupted run from checkpoints |
verify |
Value-free audit of a completed run |
validate |
Validate mask-rules.yaml syntax/schema |
gen-salt |
Emit a cryptographically random 64-char salt |
generate-ci |
Write CI/CD workflow templates |
install-pack |
Fetch, verify, and merge a config pack |
migrate-config |
Upgrade a config between schema versions |
report |
Render a compliance report for a run |
schema config |
Print the mask-rules.yaml JSON Schema |
catalog inspect |
Introspect the source schema |
Global options¶
These apply to the default (no-subcommand) invocation:
| Option | Env var | Default | Description |
|---|---|---|---|
--log-level |
PRIVACI_LOG_LEVEL |
info |
Logging level (debug, info, warning, error). |
--config |
— | /config/mask-rules.yaml |
Path to mask-rules.yaml. |
--source |
SOURCE_DB_URL |
— | Source DB URL or secret URI. |
--target |
TARGET_DB_URL |
— | Target DB URL or secret URI. |
--dry-run |
— | false |
Pre-flight only; do not write rows. |
--no-audit-table |
— | false |
Skip _privaci.audit_log writes. |
--prometheus-port |
— | off | Serve Prometheus metrics on this port. No port is opened unless set. |
All lifecycle output is emitted as JSON-lines on stdout; see
observability.md.
--help works at every level (privaci --help, privaci run --help).
privaci run¶
Execute a masking run: resolve secrets, run pre-flight, replicate schema, and stream masked rows to the target.
| Option | Env var | Default | Description |
|---|---|---|---|
--config |
— | /config/mask-rules.yaml |
Path to mask-rules.yaml. |
--source |
SOURCE_DB_URL |
— | Source DB URL or secret URI. |
--target |
TARGET_DB_URL |
— | Target DB URL or secret URI. |
--dry-run |
— | false |
Pre-flight + plan only; no writes. |
--no-audit-table |
— | false |
Skip _privaci.audit_log writes (run row still recorded). |
--prometheus-port |
— | off | Serve Prometheus metrics on this port (off by default). |
export SOURCE_DB_URL=postgresql://postgres:dev@127.0.0.1:55432/privaci_source
export TARGET_DB_URL=postgresql://postgres:dev@127.0.0.1:55433/privaci_target
export ANONYMIZATION_SALT="$(privaci gen-salt)"
privaci run --config mask-rules.yaml
# Streaming public.users (~200 rows)
# Streamed public.users: 200 row(s)
# Run 019eaca5-… succeeded: 6 table(s), 900 row(s).
Interrupting with Ctrl+C (SIGINT) finishes the in-flight batch, marks the run
interrupted, and exits 130. Continue with resume.
privaci dry-run¶
Run pre-flight checks and print the per-table action plan, including which columns auto-detect will mask or flag for review. Never writes rows.
| Option | Env var | Default | Description |
|---|---|---|---|
--config |
— | /config/mask-rules.yaml |
Path to mask-rules.yaml. |
--source |
SOURCE_DB_URL |
— | Source DB URL or secret URI. |
--target |
TARGET_DB_URL |
— | Target DB URL or secret URI. |
--report |
— | — | Write a markdown auto-detect report to this path. |
privaci dry-run --config mask-rules.yaml
# Pre-flight OK (6 table(s) in source):
# Auto-detect: 12 column(s) to mask, 3 uncertain for review
# public.users: strategy=transform (~200 rows)
# mask: email -> fake/email (autodetect)
privaci dry-run --config mask-rules.yaml --report detection.md
privaci resume¶
Continue an interrupted run from _privaci.table_checkpoints. Resumes only when
the config, source, and salt fingerprints match the interrupted run (the
five-condition gate); otherwise exits 2.
| Option | Env var | Default | Description |
|---|---|---|---|
--config |
— | /config/mask-rules.yaml |
Path to mask-rules.yaml. |
--source |
SOURCE_DB_URL |
— | Source DB URL or secret URI. |
--target |
TARGET_DB_URL |
— | Target DB URL or secret URI. |
--no-audit-table |
— | false |
Skip _privaci.audit_log writes. |
privaci resume --config mask-rules.yaml
# Skipping public.users (already done)
# Streaming clinical.visits (~300 rows)
# Run 019eaca5-… resumed: 5 table(s), 700 row(s).
Tables already marked done are skipped; in-progress tables restart from their
last_pk_value.
privaci verify¶
Audit a completed run by comparing the target against the source. Value-free:
reports only counts, rates, and verdicts — never raw cell values — so it is safe
in any environment. Exits 1 on any failing check (warnings do not fail).
| Option | Env var | Default | Description |
|---|---|---|---|
--config |
— | /config/mask-rules.yaml |
Path to mask-rules.yaml. |
--source |
SOURCE_DB_URL |
— | Source DB URL or secret URI. |
--target |
TARGET_DB_URL |
— | Target DB URL or secret URI. |
--sample-size |
— | 1000 |
Rows per table to sample for row-level checks. |
privaci verify --config mask-rules.yaml
# Verification: 77 passed, 0 warning(s), 0 failure(s).
privaci verify --config mask-rules.yaml --sample-size 5000
See Verifying a run for the full check list.
privaci validate¶
Validate mask-rules.yaml against the schema. Connectivity checks run later
during run/dry-run. Exits 3 on invalid config.
| Option | Default | Description |
|---|---|---|
--config |
/config/mask-rules.yaml |
Path to mask-rules.yaml. |
privaci validate --config mask-rules.yaml
# Config mask-rules.yaml is valid.
privaci gen-salt¶
Emit one cryptographically random 64-character (256-bit) hex salt to stdout,
generated with the secrets module.
privaci gen-salt
# 3f9a…(64 hex chars)
export ANONYMIZATION_SALT="$(privaci gen-salt)"
Each invocation produces a distinct value. Never commit the salt; store it in a secret manager.
privaci generate-ci¶
Write ready-to-commit CI/CD workflow templates for a chosen platform.
| Option | Default | Description |
|---|---|---|
--platform |
(required) | github-actions, gitlab-ci, or k8s-cronjob. |
--output-dir |
. |
Directory to write generated files into. |
privaci generate-ci --platform github-actions
# Wrote .github/workflows/privaci-refresh.yml
# Wrote docs/privaci-setup.md
privaci generate-ci --platform gitlab-ci
privaci generate-ci --platform k8s-cronjob --output-dir deploy/
| Platform | Files written |
|---|---|
github-actions |
.github/workflows/privaci-refresh.yml, docs/privaci-setup.md |
gitlab-ci |
.gitlab-ci.yml |
k8s-cronjob |
privaci-cronjob.yaml |
An unknown platform exits 3.
privaci install-pack¶
Fetch a vertical config pack, verify its Ed25519 manifest signature, preview the
merge, and (after confirmation) merge it into the local config. Invalid
signatures exit 3; no local file is modified until you confirm.
| Argument / Option | Default | Description |
|---|---|---|
NAME (argument) |
(required) | Pack name, e.g. hipaa. |
--config |
/config/mask-rules.yaml |
Local config to merge into. |
--registry-url |
https://raw.githubusercontent.com/boundarylogic/config-packs/main |
Base URL for pack manifests. |
--local-pack-dir |
— | Offline directory containing <name>/manifest.json. |
--yes |
false |
Apply the merge without prompting. |
privaci install-pack hipaa --config mask-rules.yaml
# Pack would change:
# top-level: strict_autodetect
# add table: clinical.patients
# Apply this pack to the local config? [y/N]:
privaci install-pack hipaa --config mask-rules.yaml --yes
privaci install-pack hipaa --local-pack-dir ./packs --config mask-rules.yaml
privaci migrate-config¶
Upgrade a config file between schema versions. Shipped from v1 even when no
migrations are defined; a no-op when --from equals --to.
| Argument / Option | Description |
|---|---|
PATH (argument) |
Path to the config file to migrate. |
--from |
Current schema version. |
--to |
Target schema version. |
privaci migrate-config mask-rules.yaml --from 1.0 --to 1.0
# No migration needed.
A version the engine cannot satisfy exits 3 with the exact invocation needed.
privaci report¶
Render a compliance report for a completed run. Community mode emits a JSON stub; signed PDF reports require the commercial layer.
| Option | Default | Description |
|---|---|---|
--run |
(required) | Run UUID to report on. |
--format |
json |
Output format (json; pdf is commercial). |
--output |
(stdout) | Write report bytes to this path. |
privaci report --run 019eaca5-32d9-7957-9b00-43d088b7ec6e --format json
privaci report --run 019eaca5-… --format json --output report.json
privaci schema config¶
Print the mask-rules.yaml JSON Schema to stdout. Useful for editor validation
or generating documentation.
privaci schema config > mask-rules.schema.json
privaci catalog inspect¶
Introspect the source schema and print tables, the FK-aware load order, and any warnings (e.g. cyclic or polymorphic FKs). Read-only.
| Option | Env var | Description |
|---|---|---|
--source |
SOURCE_DB_URL |
Source DB URL or secret URI. |
privaci catalog inspect --source "$SOURCE_DB_URL"
# public.users (~200 rows)
# public.orders (~540 rows)
# Load plan: [public.users] -> [public.orders]
Related¶
- Configuration reference — the
mask-rules.yamlformat. - Error codes — exit codes and message format.
- State & audit schema — what
run/resumewrite to_privaci.