How to Use CLI Commands

The oaa CLI ships a set of commands for inspecting configs, previewing data, scaffolding new integrations, and managing objects in your Veza tenant — all without running a full sync. This guide walks through the most common tasks. For the full argument list of every command, see the CLI Commands Reference.

Inspect a config before running it

Before running a sync, check what transforms, entity types, and hooks are available, and confirm your config’s JSON Schema is valid:

oaa list_transforms
oaa list_entity_types
oaa show_entity --entity_type=LocalRole
oaa list_hooks
oaa config_schema

show_entity is useful when you’re not sure which fields a field_mapping needs to populate for a given destination type — it lists the required and optional oaaclient fields and the relationship methods (add_*) available on that entity.

Validate and explode a config

Run validate_config before every sync to catch structural problems early, and use check_env to make sure every ${VAR} your config references is actually set:

oaa validate_config --config_file=./config.yaml
oaa check_env --config_file=./config.yaml

If your config uses !include directives to split settings across multiple files, explode_config writes out the fully-resolved single file — handy for debugging include order or sharing a config with someone who doesn’t have your include tree:

oaa explode_config --config_file=./config.yaml --output=./resolved.yaml

Preview and validate data before mapping

preview and preview_mapped let you see what a source returns before committing to a full run — preview shows the raw fetched records, preview_mapped shows them after field_mapping and transforms are applied:

oaa preview --source_name=users --limit=5
oaa preview_mapped --source_name=users --limit=5

Once your field_mapping is in place, run validate_mappings to confirm every mapped field name actually exists in the fetched data — it flags typos and suggests close matches:

oaa validate_mappings --config_file=./config.yaml

Test a single transform

To check how a transform behaves against a sample value, without editing your config or running a sync:

oaa test_transform --name=date_convert --value="2024-01-15"

Scaffold a new integration

init generates a full project skeleton — config.yaml, a Python module per source, sample.env, and requirements.txt:

oaa init myapp --num_sources=2 --source_names=users,roles

To add a source to an existing config later, use generate_source. For rest-api and custom source types it also creates the module file from the standard template:

oaa generate_source rest-api myapi --config_file=./config.yaml

To scaffold a hook function for a specific lifecycle event, use generate_hook:

oaa generate_hook PRE_TRANSFORM --target=users

Manage providers and datasources in your Veza tenant

These commands talk directly to your Veza tenant — set VEZA_URL and VEZA_API_KEY first (see the Environment Variables Reference).

List what’s already in the tenant:

oaa list_providers --details=True
oaa list_datasources --provider=my-app

Look up a specific provider or datasource, including current sync status:

oaa show_provider --name=my-app
oaa provider_status --name=my-app
oaa show_datasource --name=my-datasource --provider=my-app

Rename or export a provider:

oaa rename_provider --old_name=my-app --new_name=my-app-v2
oaa export_provider --name=my-app --format=csv --output_dir=./my-app-export

Deleting a provider or datasource requires an explicit --confirm=True — without it, the command reports what it would delete and stops:

oaa delete_provider --name=my-app              # dry run, nothing deleted
oaa delete_provider --name=my-app --confirm=True
oaa delete_datasource --name=my-datasource --confirm=True --cascade=True

Download and compare saved queries

download_query and compare_queries also require VEZA_URL and VEZA_API_KEY, but read them strictly from the environment (not from config.yaml) — see the reference doc’s Query & Diff Commands section for details.

oaa download_query --query_id=abc123 --output=./results.csv
oaa compare_queries --query1=abc123 --query2=def456 --key_field=user_id

run_query (ad-hoc Veza Query Language execution) is implemented but not yet usable — the underlying API endpoint doesn’t exist yet. Use download_query against a saved query instead.

Diff two config files

To see exactly what changed between two versions of a config — connections, sources, field mappings, transforms, and hooks:

oaa diff_config --config_file=./config.yaml --compare_file=./config-v2.yaml

Get machine-readable output

Every command above supports a --json flag, which prints the result as indented JSON instead of formatted text — useful for piping into jq or consuming from a script:

oaa list_providers --json | jq '.[].name'

Note that a few commands (check_env, validate_mappings, diff_config) only set a non-zero exit code in their normal text-mode output; with --json they always exit 0, so a script checking for failure via --json needs to inspect the JSON payload itself rather than the exit code. See the reference doc for exact details per command.

Review an integration before running it

Before pushing a new integration to Veza, run static analysis and validation:

oaa review --path=./my-integration
oaa validate_integration --path=./my-integration --skip_mock=True

review runs 26 deterministic checks (config, code quality, pagination, etc.). validate_integration --skip_mock runs checks without needing API credentials: validates config, checks environment variables, validates field mappings, and runs the review. Both exit 1 if any critical issue is found.

For a full validation pipeline including mock data run and payload inspection:

oaa validate_integration --path=./my-integration

Or against a live API (if credentials are available):

oaa validate_integration --path=./my-integration --live=True

Work with payload files

After a local test run, inspect and anonymize the output payload:

oaa run --save-json=./payload.json --no-push
oaa anonymize --input=./payload.json --output=./safe.json
oaa validate_payload --payload=./payload.json --config=./config.yaml

anonymize redacts sensitive data (emails, tokens, SSNs, etc.) with deterministic fakes — use --audit to see what would be redacted without modifying the file, or --schema to extract field structure only.

validate_payload reports on field presence/null rates, date formats, role permission coverage, relationships, and shape diffs between config and payload.

Parse an API specification

When building a new REST API integration, parse the provider’s spec to discover endpoints, authentication schemes, and available operations:

oaa parse_spec --input=./openapi.yaml
oaa parse_spec --input=https://api.example.com/openapi.json --tag=users
oaa parse_spec --input=./spec.json --include_schemas=True

Supports OpenAPI 3.x, Swagger 2.0, and Postman Collections. With --tag, filter to a specific group of endpoints. With --include_schemas, include component/definition schemas for field-level structure.

Get a sample integration

Copy a bundled sample to use as a starting point:

oaa show_sample --list
oaa show_sample --name=custom-app-users-groups-roles
oaa show_sample --name=hris-employees-groups --output=./my-hris
oaa show_sample --filter=idp

--list shows available samples. --name copies a specific sample to a destination (default: ./<name>). --filter searches samples by substring. Bundled samples include CUSTOM_APP (users, groups, roles, resources), HRIS (employees, groups, manager chain), and IDP (users, groups, identity coercion) patterns.