Skip to main content

Tenant selection

Tenants are the only configuration source. Create a tenant through guided prompts or register an existing Prisma AIRS JSON file, select it, and every command reads that file. Existing files can be read-only: registering, switching, reading, and deleting registrations never modify the source configuration or copy its credentials.

Set up without a JSON file​

airs-cli tenant create development
# Prompts, one at a time: TSG ID, OAuth client ID, and a hidden OAuth client secret.
airs-cli tenant switch development
airs-cli tenant set development defaultOutput yaml
airs-cli tenant set development scanConcurrency 3
airs-cli tenant set development airsApiKey
# Hidden prompt for the runtime scanning key.
airs-cli tenant read

create waits for all three required values before saving anything. Ctrl+C cancels setup without registering a partial tenant (exit 130). This configures access to an existing cloud tenant; it does not provision a tenant or service account.

set <name> <key> [value] changes just one setting in that tenant's file, without changing the active selection. Omit the value to be prompted. Credentials use hidden prompts and cannot be passed as command-line arguments. Values are schema-validated; unrelated fields are preserved. Credential fields cannot be cleared. The registered mgmtTsgId is pinned: create another tenant to use a different TSG.

unset <name> <key> removes one setting so the default applies again; get <name> <key> prints one value with credentials redacted; path [name] prints the file path.

For automation, pipe a secret from your secret manager or private file:

airs-cli tenant create development --tsg-id 100 --client-id client-100 \
--client-secret-stdin < /secure/oauth-secret.txt
airs-cli tenant set development mgmtClientSecret --stdin < /secure/rotated-secret.txt

Stdin accepts one nonempty value, up to 64 KiB, with an optional final newline. Without a terminal, supply the creation IDs and --client-secret-stdin, or use --config. Do not combine --config with new-config options. Neither creation nor editing tests OAuth access; a successful save confirms local configuration only. Run airs-cli doctor for that.

New configs are stored under configs/ alongside the tenant registry, with a unique filename, directory mode 0700, and file mode 0600 on POSIX. Secrets are stored in that private JSON file, not encrypted, and never in the registry. Back up and protect these files. tenant set and tenant unset require a writable regular file and parent directory; they do not bypass read-only permissions. Updates use a per-config lock and atomic replacement with mode 0600. Deleting a registration retains even CLI-created configs.

Use an existing JSON file​

airs-cli tenant create development --config /secure/development.json
airs-cli tenant create production --config /secure/production.json
airs-cli tenant list --output json
airs-cli tenant switch development
airs-cli tenant read
airs-cli tenant read production --output yaml
airs-cli tenant delete production --force

create --config registers an existing file, not a new cloud tenant or service account. Each file must contain mgmtClientId, mgmtClientSecret, and mgmtTsgId. Add other keys to that same file as needed (see configuration options). A registration does not become active until you run switch. Names are 1–64 letters, digits, hyphens, or underscores, beginning with a letter or digit.

CommandBehavior
create <name>Prompt for TSG ID, client ID and hidden secret; create a private config
create <name> --config <path>Validate and register an existing config; resolve its real absolute path
switch <name>Validate its pinned TSG identity and persist the selection for subsequent CLI processes
set <name> <key> [value] [--stdin]Update one setting; prompt if omitted, hide credentials, preserve selection
unset <name> <key>Remove one non-credential setting so the default applies
get <name> <key> --output <format>Print one setting, credentials redacted
list --output <format>Show names, selected status, TSG IDs, and file paths; no credential reads
read [name] --output <format>Show file settings with all credential values redacted; defaults to the selected tenant
path [name]Print a tenant's config file path; defaults to the selected tenant
delete <name> [--force]Unregister a tenant; keep its config file; clears the selection if it was selected

list, read, and get support pretty, table, markdown, csv, json, and yaml. There is intentionally no --reveal. A missing or invalid selected config fails closed; tenant list, tenant switch, and tenant delete remain available for recovery. With no tenant selected, every API command stops with No tenant selected and names the registered tenants.

Registry and precedence​

The small, versioned registry contains paths and TSG IDs, not credentials. It lives at $XDG_STATE_HOME/prisma-airs/tenants.json, or ~/.local/state/prisma-airs/tenants.json. Use PRISMA_AIRS_TENANTS_PATH to isolate a registry for a container, automation job, or shell session. Updates use a private lock and atomic replacement; new directories use mode 0700 and the registry uses 0600 on POSIX systems. Back up the registry and its referenced config files separately. If a process leaves a lock behind, confirm that no writer is running before removing that specific .lock file.

Config resolution is: CLI flags, then the selected tenant's file, then defaults. No environment variable supplies a configuration value, and a .env file is not loaded. airs-cli doctor names the selected tenant and TSG, validates the file against its pinned identity, lists any PANW_* or PRISMA_AIRS_CONFIG_PATH variables still set in the shell (they are ignored), and phrases every remedy as airs-cli tenant set <name> <key>.

Selection affects new commands, not already running processes. For parallel jobs targeting different tenants, give each job its own registry through PRISMA_AIRS_TENANTS_PATH.

For disposable Docker containers, persist the registry separately from the read-only config mount (for the published root-based image, mount a volume at /root/.local/state/prisma-airs). Otherwise a selection disappears when the container is removed. Backups likewise need an explicit path on a writable bind mount to survive container removal. Config paths are interpreted inside the container.

Cross-tenant profile migration​

airs-cli tenant switch development
airs-cli runtime profiles backup --all --output-file ./profiles.json
airs-cli tenant switch production
airs-cli runtime profiles restore ./profiles.json --dry-run --output json
# Review the destination and dependency plan before executing:
airs-cli runtime profiles restore ./profiles.json --expect-tsg 200 --force

Replace 200 with the actual destination TSG. See the profile migration guide for DLP mappings, conflicts, limitations, and live acceptance evidence.

Guided setup acceptance output​

Captured on 2026-09-08 with synthetic credentials and an isolated local registry; this is a terminal interaction test, not a cloud authentication claim. Terminal control sequences have been removed; no credential value is included below.

$ airs-cli tenant create guided-demo
✔ Tenant service group ID (mgmtTsgId): 100
✔ OAuth client ID (mgmtClientId): client-100
✔ OAuth client secret (mgmtClientSecret):
✓ Registered guided-demo (TSG 100); private config created. Use airs-cli tenant switch guided-demo.

$ airs-cli tenant set guided-demo defaultOutput
✔ defaultOutput: yaml
✓ Updated defaultOutput for tenant guided-demo; selection unchanged.

$ airs-cli tenant create cancelled-demo --tsg-id 100 --client-id client-100
? OAuth client secret (mgmtClientSecret): [input is masked]
# Ctrl+C
Cancelled; no configuration saved.

Cancellation exited 130 and left only the completed guided-demo registration and its config; selection remained unchanged. tenant read guided-demo --output json returned defaultOutput: yaml and [REDACTED] for mgmtClientSecret. Separate built-CLI integration tests verified stdin setup, secret rotation, individual endpoint updates, and OAuth/profile retrieval against a local HTTP test API. The existing two-tenant profile backup/restore integration workflows also passed.