CLI
verdictan control
You can keep organization resources in one YAML file, the control manifest. Use verdictan control export to write the current resources to a file. Use verdictan control plan to see the changes that the file causes. Use verdictan control apply to make the changes.
The control manifest is not the gateway policy config. For providers, routes, and the policy chain, use policy-config.yaml.
Before you start
You need:
- An API credential. Set
VERDICTAN_API_TOKEN, or runverdictan auth login. The CLI does not accept a token flag. - Permission to read each resource group for
exportandplan, and permission to change it forapply. - For each manifest secret: the environment variable that the secret names, set in the shell that runs
apply.
Start from your saved settings
-
Write the current resources to a file:
verdictan control export --file control-manifest.yamlThe command prints
exported to control-manifest.yaml. AnExport summary:line on standard error gives the number of resource groups that exported. -
Make a plan for the file:
verdictan control plan --file control-manifest.yamlSome resource types always show as a create or an update, also when nothing changed. Examine the resource groups table for these types. Find the cause of each other create or update before you continue.
-
Edit one IAM policy in the file. For example, change its
description. Then make the plan again. The output is similar to this:plan: 0 create(s) 1 update(s) 0 delete(s) 3 no-op(s) ~ iam.policy evidence-read ~ description (dry-run — no changes applied; run `verdictan control apply` to reconcile) -
When the plan contains only the changes you want, apply the file:
verdictan control apply --file control-manifest.yamlThe command prints the plan and asks for confirmation. Type
yes. It printsapplied <n> operation(s)andcontrol-plane reconciled successfully. -
Make the plan again to confirm the result. For an IAM policy, the line moves to the no-op count.
Manifest format
A manifest has version: "1" and a resources object. The CLI rejects other versions and unknown resource groups. The CLI reads .json files as JSON and all other files as YAML.
version: "1"
resources:
secrets:
- name: openai-production-key
env: VERDICTAN_OPENAI_API_KEY
description: Production provider credential
iam:
policies:
- name: evidence-read
description: Read governance evidence
statements:
- Effect: Allow
Action:
- events:read
- exports:read
Resource:
- "*"
roles:
- name: evidence-reviewer
policies:
- evidence-read
teams:
- name: security-review
description: Governance evidence reviewersNames identify resources. Keep each name stable and unique in its resource type. Budgets refer to a team, user, or agent by name or email. A role refers to IAM policies by name, and each name must be a policy in the same manifest.
A manifest secret has name, env, and an optional description. It has no value field. At apply time, the CLI reads the value from the environment variable in env. The API stores the value as a secret record. A gateway does not use these records as provider keys. See Manage Secrets and Credentials.
The CLI checks the manifest before it contacts the API. These checks include the version, empty names, empty env values, and role references to unknown policies.
This table shows how plan compares each resource group with the remote state:
| Group | Plan result for a resource that exists | Deleted by --prune |
|---|---|---|
secrets | Always an update. The value can change in the environment. | Yes |
iam.policies | An update when description or statements changes | Yes |
iam.roles | Always a no-op. Changes are not applied. | Yes |
teams | Always a no-op. Each listed member is always a create. | Yes, teams only |
users | Add the listed roles and team memberships. With neither list, a no-op. | Remove organization membership |
platform_provider_bundles | An update when a field changes | Archived |
agents | An update when a field changes | Yes |
budgets | An update when a field changes | Yes |
regulated_execution_profiles | Always an update | Yes |
approval_policy | Update the one organization approval policy | No |
prompt_evaluation_suites | An update when a field changes | Yes |
hosted_gateway_bindings | Always an update | No |
auth_org_policy | Update organization SSO and password sign-in settings | No |
Users and organization settings
For a new user, the CLI creates an invitation. Set exactly one role and, optionally, one team:
version: "1"
resources:
users:
- email: developer@example.com
roles: [evidence-reviewer]
teams: [security-review]The role and team must exist when the invitation runs. Use their names from verdictan role list and verdictan team list. For an existing user, listed roles and teams are added. Omitted memberships are not removed. With --prune, removal affects organization membership, not the user's account.
The API has one approval policy per organization. Use approval_policy, not a named approval_policies list:
version: "1"
resources:
approval_policy:
required_actions:
destructive_actions: true
high_cost_requests: false
sensitive_data_access: true
required_approvals: 1
timeout_hours: 24
break_glass:
enabled: false
allow_requester_override: false
post_review_required: false
review_window_hours: 24
reviewer_subject_ref: ""
auth_org_policy:
required_sso: false
local_auth_allowed: trueThe approval count must be 1 or 2. Time limits must be positive. If break-glass access and post-review are enabled, supply reviewer_subject_ref. Approval settings use the org:settings permission. Authentication settings use sso:read to plan and sso:write to apply.
The CLI rejects approval_policies, collaboration_defaults, and hosted_gateway_policy before it contacts the API. For auth_org_policy, only required_sso and local_auth_allowed are supported. Legacy domain, JIT, invite-only, and popup-origin fields also stop validation before any changes. Use the SSO API for domain and identity-provider settings.
verdictan control export
verdictan control export reads the resources of the authenticated organization and writes them as a manifest. The export does not contain secret values, team members, or user teams and roles.
Usage
verdictan control export [OPTIONS]Options
| Flag | Description |
|---|---|
--file <path> | Write the manifest to this file. Without this flag, the command prints the manifest to standard output. |
--include-secret-stubs | Include one entry for each secret, with env: <SET_ENV_VAR>. Without this flag, the export has no secrets list. |
--json | Write JSON, not YAML. |
--allow-partial | Write the manifest when one or more resource groups fail. |
--config <path> | Use this CLI config file. |
--api-url <url> | Use this API URL. |
--profile <name> | Use this profile. The default is default. |
--region <region> | Send the API calls to this region. |
Examples
# Print the manifest as YAML
verdictan control export
# Write a file that includes secret entries
verdictan control export --file control-manifest.yaml --include-secret-stubsAfter an export with --include-secret-stubs, replace each <SET_ENV_VAR> with the name of a variable that holds the secret in the apply environment. Do not put the secret value in the file.
When a resource group fails, the command stops with <n> resource type(s) failed to export; rerun with --allow-partial to emit a partial manifest. The Export summary: line lists the failed groups with their HTTP status. With --allow-partial, the command writes the manifest without the failed groups. A route that returns 404 does not count as a failure. The command exports that group as empty.
verdictan control plan
verdictan control plan calculates the operations that apply runs for the same file. It does not change remote resources.
Usage
verdictan control plan [OPTIONS]Options
| Flag | Description |
|---|---|
--file <path> | Manifest file. The default is control-manifest.yaml. |
--prune | Include delete operations for remote resources that are not in the manifest. |
--json | Print the plan as one JSON object. |
--config <path>, --api-url <url>, --profile <name>, --region <region> | The same as for export. |
Examples
# Plan for the default file
verdictan control plan
# Plan that includes deletions, as JSON
verdictan control plan --file control-manifest.yaml --prune --jsonIn text mode, the first line is plan: <n> create(s) <n> update(s) <n> delete(s) <n> no-op(s). Each change follows on one line: + for a create, ~ for an update, and - for a delete, then the resource type and the name. The command does not print no-op lines. When there are no changes, it prints no changes — control-plane is up to date.
In JSON mode, the object has dry_run: true, prune, a summary object with creates, updates, deletes, and no_ops, and the ops array.
verdictan control apply
verdictan control apply calculates the plan again and then runs the operations. It runs creates and updates first, in the order of the resource groups table. Then it runs deletes in the opposite order.
Usage
verdictan control apply [OPTIONS]Options
| Flag | Description |
|---|---|
--file <path> | Manifest file. The default is control-manifest.yaml. |
--prune | Delete remote resources that are not in the manifest. |
--yes | Do not ask for confirmation. |
--json | Print the result as one JSON object. JSON mode does not ask for confirmation. |
--config <path>, --api-url <url>, --profile <name>, --region <region> | The same as for export. |
Examples
# Apply after confirmation
verdictan control apply --file control-manifest.yaml
# Apply in CI, without a prompt
verdictan control apply --file control-manifest.yaml --yes --jsonIn text mode, the command prints the plan and then Type 'yes' to continue:. Other answers stop the command with aborted — no changes applied and exit code 0.
In JSON mode, the object has applied, prune, summary, successful, and failed. applied is true only when failed is empty.
Delete resources that are missing from the file
--prune deletes each remote resource that the manifest does not list, in each group that supports it. An empty or missing list counts as a list with no entries. For example, a manifest without secrets deletes all secrets. Only a missing iam block is skipped.
Use --prune only when the manifest declares all resources that you manage. Do not use it with an export that has missing groups, or with an export made without --include-secret-stubs.
-
Make the deletion plan:
verdictan control plan --file control-manifest.yaml --prune --json -
Examine each operation with
"action": "delete". -
Apply with the same file and flag:
verdictan control apply --file control-manifest.yaml --pruneThe prompt says
This will create, update, AND DELETE resources listed above.
Limits and failure behavior
applystops at the first failed operation. The operations that completed before it stay applied. Make the plan again to see the remaining changes.- In text mode, a failure prints
error: <type> <name> — <message>and the command exits with code4. In JSON mode, the command exits with code0. Readappliedandfailedin automation. - A manifest error, such as
unsupported manifest version "2" (expected "1"), exits with code2. A missing credential exits with code3andmissing api token (set VERDICTAN_API_TOKEN or run `verdictan auth login`). applycalculates the plan again. Changes made by other operators after yourplanchange the result.- A new role is created without its
policies. The CLI ignores the attach failure. Attach the policies after apply. - The CLI adds team members by email only. It does not send member
roles. For a user,teamsandrolesadd memberships. - An existing team keeps its description. The manifest
descriptionapplies only when the CLI creates the team. --prunedoes not remove team members, agent gateway links, hosted gateway bindings, or the organization settings.
Next steps
- IAM, Members, Teams, and Roles: manage policies, roles, users, and teams one at a time.
- verdictan agent: create and change the agents that a manifest declares.
- Manage Secrets and Credentials: store the secrets that a manifest refers to.
- Policy Lifecycle: manage the gateway policy config.