oz0 tenant tool-policy set
For: Operators and developers looking up a command.
Change a tenant's tool policy. --read-only, --destructive, --open-world and --undeclared take allow, approve or refuse. Each --rule is <tool>.<function>=<action>, where * in the name matches anything, such as github.merge=refuse or web.=allow, or names one plugin's functions by address, such as github/oz0_github.=approve; the first rule that matches a function decides.
A rule may end with conditions after if: plugin=<names>, publisher=<names> and source=<kinds> (git, workspace, bundle, oci, hub, mcp) for the calling plugin, other-plugins for calls of another plugin's functions only, and kind=<kinds> (read_only, not_read_only, destructive, open_world, undeclared).
It may end with a CEL condition over each call after when: args, mcp.tool.name, mcp.tool.target, caller.plugin, caller.agent and the like, with has() as the only macro; the rule then decides only the calls it holds for, in the runtime and again at the edge, and a condition that fails to evaluate never loosens a decision. --rule replaces the rules the policy had, unless --keep-rules adds to them; --defaults starts again from the defaults.
A rule that approves may say who decides: decided-by=<who>,... where each is role:admin, team:<name>, user:<name> or key:<API key ID> (an integration that decides with that key; no other key may), and not-starter refuses the job's starter as the decider (four eyes). --recheck-after is how long an approval or a question may wait before it is checked again when it resolves (an hour by default).
--taint-default-when narrows the built-in taint-default rule to the calls its CEL condition holds for, such as a service the tenant trusts left out; it loosens, so it takes a reason. To add, change or remove one rule, with flags instead of conditions inside its text, use oz0 policy.
Usage
oz0 tenant tool-policy set [flags]
Flags
| Flag | Type | Default | Description |
|---|---|---|---|
--approval-deadline | string | 24h | how long the tenant's approvals wait at most when nothing more specific says, 1m to 720h |
--decision-ref | string | the decision or case the change follows, such as a case number (at most 200 characters) | |
--defaults | bool | start from the default policy instead of the tenant's | |
--destructive | string | what happens to calls to destructive functions: allow, approve or refuse | |
--escalation | string | the tenant's escalation ladder: default, off (with --escalation-reason), or steps such as 0.25:deciders,0.5:owner,0.75:admins | |
--escalation-reason | string | why the tenant's ladder is off; the audit trail keeps it | |
--gate-rule | stringArray | add an origin or sequence rule as JSON, such as '{"match":"mail.send","action":"refuse","origins":{"to":"request"}}' or '{"match":"*","action":"approve","sequence":{"after":{"labels":{"level":"confidential"}},"then":{"outbound":true},"within":"tree"}}'; repeatable; mode, expires_at and rationale as for any rule | |
--json | bool | print JSON instead of a table | |
--keep-rules | bool | add --rule to the policy's rules instead of replacing them | |
--label-egress | stringArray | add a rule that refuses calls of functions that can send data out once the job read something at LEVEL or above (LEVEL, or LEVEL:approve to ask a person instead); it starts in shadow mode, so it decides nothing until it is promoted; repeatable | |
--no-origin-record | stringArray | stop vouching for a pattern given with --origin-record; repeatable | |
--open-world | string | what happens to calls to open-world functions: allow, approve or refuse | |
--origin-default | string | on, or off: the built-in rule that asks a person when a sensitive argument's value is below the floor its schema sets (x-oz0-origin); off loosens and needs a reason | |
--origin-record | stringArray | vouch for a function's results as tenant records (<tool>.<function>, * for anything) when its schema says x-oz0-origin-source: record; repeatable; loosens and needs a reason | |
--preset | stringArray | add a shipped sequence rule: untrusted-then-consequential or confidential-then-egress; repeatable; a preset the policy has is kept as it is | |
--read-only | string | what happens to calls to read-only functions: allow, approve or refuse | |
--reason | string | why, required for every governance change (at most 500 characters; default $OZ0_REASON); the audit log keeps it | |
--recheck-after | duration | check an approval again when it resolves after waiting longer than this, such as 1h (at least 1m) | |
--rule | stringArray | <tool>.<function>=<action>, * matching anything in the name; repeatable, in order | |
--taint-default | string | on, or off: the built-in rule that asks a person before a tainted job's outbound calls; off loosens and needs a reason | |
--taint-default-when | string | the taint-default rule's CEL condition, to narrow it (its own is job.tainted && tool.outbound); loosens and needs a reason | |
--tenant | string | default | tenant |
--undeclared | string | what happens to calls to functions without annotations, or silent on destructiveHint: allow, approve or refuse |
Inherited flags
| Flag | Type | Default | Description |
|---|---|---|---|
--context | string | $OZ0_CONTEXT or <config dir>/orchestrator-zero/context.json | CLI context file written by server init |
--log-level | string | info | log level: debug, info, warn or error |
See all oz0 commands and the global flags.