ctrlrun command reads the policy in the working directory (ctrlrun.yaml, or the
file $CTRLRUN_CONFIG names) and the store beside it, .ctrlrun/state.db, unless
--store-url or $CTRLRUN_STORE_URL names another. A command that reads evidence creates
nothing and migrates nothing. Each section below is the command’s own --help, verbatim.
ctrlrun
Usage: ctrlrun [OPTIONS] COMMAND [ARGS]...
CTRLRun — the execution safety layer for AI agents.
Options:
--version Show the version and exit.
--help Show this message and exit.
Commands:
approve Grant a pending approval request.
delegate Create a delegated grant beneath an existing one.
demo Run the five scenarios, in process, with no network.
deny Refuse a pending approval request.
effects Show the logical effects this store knows about.
gateway Front an MCP server, applying this directory's policy to...
init Write a starter ctrlrun.yaml and create .ctrlrun/.
inspect Show one action's whole history: proposal, decision,...
mcp-operator Answer approvals from an MCP client, over loopback...
policy Propose a policy change, or replay one against what already...
receipts Show the receipts this store holds.
resolve Say what actually happened to an effect with an unknown...
revoke Revoke a delegation, and with it every delegation beneath it.
scan Report the consequential call sites and policy entries...
stats Count what this store's receipts say, from the local store...
verify Run the declared guarantees against this configuration...
ctrlrun init
Usage: ctrlrun init [OPTIONS]
Write a starter ctrlrun.yaml and create .ctrlrun/.
Options:
--help Show this message and exit.
ctrlrun demo
Usage: ctrlrun demo [OPTIONS]
Run the five scenarios, in process, with no network.
Options:
--help Show this message and exit.
ctrlrun approve
Usage: ctrlrun approve [OPTIONS] REQUEST_ID
Grant a pending approval request.
Options:
--store-url TEXT The store to open. Default: $CTRLRUN_STORE_URL, else the
SQLite database beside the policy (.ctrlrun/state.db, or
wherever $CTRLRUN_STATE points).
--help Show this message and exit.
ctrlrun deny
Usage: ctrlrun deny [OPTIONS] REQUEST_ID
Refuse a pending approval request.
Options:
--store-url TEXT The store to open. Default: $CTRLRUN_STORE_URL, else the
SQLite database beside the policy (.ctrlrun/state.db, or
wherever $CTRLRUN_STATE points).
--help Show this message and exit.
ctrlrun receipts
Usage: ctrlrun receipts [OPTIONS]
Show the receipts this store holds.
Options:
--last INTEGER RANGE Show only the last N. [x>=1]
--json Print the portable receipt JSON.
--verify-chain Check the receipt chain and report every break by seq
and by name.
--control ID Show only receipts citing this control id (SPEC-v0.6
§7.3).
--store-url TEXT The store to open. Default: $CTRLRUN_STORE_URL, else the
SQLite database beside the policy (.ctrlrun/state.db, or
wherever $CTRLRUN_STATE points).
--help Show this message and exit.
ctrlrun effects
Usage: ctrlrun effects [OPTIONS]
Show the logical effects this store knows about.
An effect that still **holds** part of a budget says so (SPEC-v0.9 §7.2):
`--state ambiguous` is how an operator finds what is pinning a grant, and the
hold is the reason it matters.
Options:
--state [new|reserved|executing|committed|failed|ambiguous]
Show only effects in this state.
--store-url TEXT The store to open. Default:
$CTRLRUN_STORE_URL, else the SQLite database
beside the policy (.ctrlrun/state.db, or
wherever $CTRLRUN_STATE points).
--help Show this message and exit.
ctrlrun resolve
Usage: ctrlrun resolve [OPTIONS] EFFECT_KEY
Say what actually happened to an effect with an unknown outcome.
Options:
--committed The effect did happen at the remote.
--failed The effect provably did not happen.
--store-url TEXT The store to open. Default: $CTRLRUN_STORE_URL, else the
SQLite database beside the policy (.ctrlrun/state.db, or
wherever $CTRLRUN_STATE points).
--help Show this message and exit.
ctrlrun inspect
Usage: ctrlrun inspect [OPTIONS] [ACTION_ID]
Show one action's whole history: proposal, decision, approval, effect,
receipt.
With `--grant`, show that grant's budgets instead: how much of each is
consumed over its rolling window, how much of that is **held** by effects that
have not committed, and which effect holds each part (SPEC-v0.9 §7.2).
The third number is the one that matters at 3am. A budget that refuses while
it looks nowhere near its limit is almost always one unresolved effect:
`ctrlrun resolve` clears it.
Options:
--grant TEXT Show this grant's budgets instead: consumed, held, and what
holds it.
--hop TEXT Show this hop or delegation instead: who issued it, and what
each link narrowed.
--json Emit one JSON object instead.
--store-url TEXT The store to open. Default: $CTRLRUN_STORE_URL, else the
SQLite database beside the policy (.ctrlrun/state.db, or
wherever $CTRLRUN_STATE points).
--help Show this message and exit.
ctrlrun stats
Usage: ctrlrun stats [OPTIONS]
Count what this store's receipts say, from the local store and nothing else.
No network, no aggregation service, no upload: this reads the SQLite file the
process it is diagnosing has been writing (SPEC-v0.3 §6.4).
Options:
--since TEXT Count only receipts finished at or after this: an ISO-8601
timestamp with an offset, or <n>m / <n>h / <n>d.
--json Emit one JSON object instead.
--store-url TEXT The store to open. Default: $CTRLRUN_STORE_URL, else the
SQLite database beside the policy (.ctrlrun/state.db, or
wherever $CTRLRUN_STATE points).
--help Show this message and exit.
ctrlrun verify
Usage: ctrlrun verify [OPTIONS]
Run the declared guarantees against this configuration (SPEC-v0.4).
Every scenario runs against a scratch store created and destroyed for the run.
The store an agent is using is not opened, not read and not created.
Exit codes: 0 every applicable guarantee passed and at least one was
applicable; 1 a guarantee FAILED; 2 the configuration was refused or is
unusable — which includes `mode: observe` and a configuration in which nothing
could be exercised; 3 an internal error in verify itself.
Options:
--authority FILE A standalone authority document, as `ctrlrun gateway
--authority` takes.
--json Emit one ctrlrun.verify/v1 document.
--junit FILE Also write a JUnit XML file for CI.
--only TEXT Comma-separated guarantee ids, e.g. G1,G3.
--store-url TEXT The backend to grade against: 'sqlite' (the default) or a
postgresql:// URL. Verify runs in a scratch store it creates
there and never opens yours.
--help Show this message and exit.
ctrlrun delegate
Usage: ctrlrun delegate [OPTIONS]
Create a delegated grant beneath an existing one.
`--as` is an **assertion**, not an authentication: it supplies the creating
principal for SPEC-v0.3 §5.3 rule 4, and it is free text typed by whoever runs
the command. The record keeps `created_via="cli"` so a reader of the evidence
can tell an act from an assertion. An agent name containing '/' cannot be
written here, because `--as a/b` would otherwise be ambiguous between the
agent `a/b` acting alone and the agent `a` acting for `b`.
Options:
--parent TEXT The grant or delegation being narrowed. [required]
--file FILE A one-grant YAML document, with the keys of SPEC-v0.3 §4.2
minus 'id'. [required]
--as TEXT The delegating principal: AGENT or AGENT/USER. Split on the
first '/'. [required]
--json Emit one JSON object instead.
--store-url TEXT The store to open. Default: $CTRLRUN_STORE_URL, else the
SQLite database beside the policy (.ctrlrun/state.db, or
wherever $CTRLRUN_STATE points).
--help Show this message and exit.
ctrlrun policy
Usage: ctrlrun policy [OPTIONS] COMMAND [ARGS]...
Propose a policy change, or replay one against what already happened.
A policy is the one file that decides every other decision, and until v0.8 it
was changed by editing it. v0.6 made the change evidenced: every receipt
records the hash of the policy that decided it. v0.8 makes it approved: **a
policy nobody approved decides nothing**, in a deployment that asks for that
with `Control(require_approved_policy=True)`.
There is no `ctrlrun policy approve`. A proposal is an ordinary approval
request, so the command that answers it is `ctrlrun approve`, and a second one
would be a second approval path (SPEC-v0.8 §8.3).
Options:
--help Show this message and exit.
Commands:
propose Propose a policy change under the policy currently in force.
replay Report which recorded decisions would change under a proposed...
ctrlrun revoke
Usage: ctrlrun revoke [OPTIONS] [DELEGATION_ID]
Revoke a delegation, and with it every delegation beneath it.
Transitive by structure and not reversible: there is no `unrevoke`, because
the operation whose safety matters is the one taken in a hurry (SPEC-v0.3
§5.7). Revoking an already-revoked delegation is idempotent and exits 0.
`--created-by` and `--under` are selectors over rows that already exist
(SPEC-v0.8 §7). Each match is revoked **exactly as one id is**: one
revocation, one record, one event, in turn, so a run that stops halfway leaves
the rows it reached revoked and the rest untouched, and a second run finishes.
A selector that matches nothing exits non-zero (§7.5), because during an
incident a mistyped name that exits 0 reads as "done".
`--by` is unchanged and means what it has always meant: who performed the
revocation.
Options:
--by TEXT Who revoked it. [default: cli:local]
--created-by TEXT Revoke every delegation this principal created: AGENT or
AGENT/USER.
--under TEXT Revoke every delegation beneath this grant or delegation
id, at any depth.
--store-url TEXT The store to open. Default: $CTRLRUN_STORE_URL, else the
SQLite database beside the policy (.ctrlrun/state.db, or
wherever $CTRLRUN_STATE points).
--help Show this message and exit.
ctrlrun mcp-operator
Usage: ctrlrun mcp-operator [OPTIONS]
Answer approvals from an MCP client, over loopback (SPEC-mcp-operator.md).
There is no --principal and no --allow-remote, and both absences are load-
bearing: a static principal cannot attribute an answer to a person (§3.1), and
a server whose read tools answer without a credential must not be the one that
opens a port (§2.1).
Options:
--listen TEXT HOST:PORT. [default: 127.0.0.1:8901]
--path TEXT The MCP endpoint path. [default: /mcp]
--principal-header TEXT Take the approver's agent from this header,
set by a proxy that authenticates them.
--user-header TEXT Take the approver's name from this header.
Required with --principal-header (SPEC-mcp-
operator §3.2).
--environment TEXT The deployment this console reads. Default:
$CTRLRUN_ENVIRONMENT, else the policy
document, else production (SPEC-v0.3 §2.5).
--max-body-bytes INTEGER [default: 1048576]
--allow-origin TEXT Repeatable.
--authority FILE Load the authority: section from a separate
YAML document (SPEC-v0.3 §8.3).
--identity-jwt Verify a bearer JWT (ctrlrun[identity]).
--identity-jwt-jwks-url TEXT Fetch keys from this JWKS (HTTPS).
--identity-jwt-public-key FILE A PEM public key file.
--identity-jwt-secret-file FILE
Read the HS* shared secret from here. Never a
flag value.
--identity-jwt-algorithms TEXT Repeatable, required. There is no default and
no wildcard.
--identity-jwt-issuer TEXT Matched exactly. Required.
--identity-jwt-audience TEXT Matched by membership. Required.
--identity-jwt-token-type TEXT Required. The token's typ, e.g. at+jwt. Pass
"" for "this issuer sets no typ".
--identity-jwt-header TEXT [default: authorization]
--identity-jwt-agent-claim TEXT
[default: sub]
--identity-jwt-user-claim TEXT Which claim names the human. Required with
--identity-jwt (SPEC-mcp-operator §3.2).
--identity-jwt-claim TEXT Repeatable: which verified claims reach the
receipt. An allow-list.
--identity-jwt-leeway FLOAT [default: 60.0]
--identity-jwt-jwks-min-refresh FLOAT
[default: 30.0]
--identity-jwt-http-timeout FLOAT
[default: 5.0]
--approver-roles-claim TEXT Which verified claim carries this issuer's
roles, for the approver entitlement of
SPEC-v0.8 §3. Without it no role can be read,
so any cited control naming one refuses.
--store-url TEXT The store to open. Default:
$CTRLRUN_STORE_URL, else the SQLite database
beside the policy (.ctrlrun/state.db, or
wherever $CTRLRUN_STATE points).
--help Show this message and exit.
ctrlrun gateway
Usage: ctrlrun gateway [OPTIONS]
Front an MCP server, applying this directory's policy to every tools/call.
Options:
--upstream TEXT The MCP server this gateway fronts.
[required]
--alias TEXT Names the upstream in 'mcp.<alias>.<tool>'.
[required]
--listen TEXT HOST:PORT. [default: 127.0.0.1:8900]
--path TEXT The MCP endpoint path. [default: /mcp]
--principal TEXT A fixed agent name, for one tenant.
--principal-header TEXT Take the agent from this header.
--user-header TEXT Take principal.user from this header.
--environment TEXT The deployment this gateway acts in. Default:
$CTRLRUN_ENVIRONMENT, else the policy
document, else production (SPEC-v0.3 §2.5).
--upstream-timeout FLOAT [default: 30.0]
--max-body-bytes INTEGER [default: 1048576]
--allow-origin TEXT Repeatable.
--allow-remote Permit a non-loopback --listen.
--public-url TEXT Where the gateway is reachable, for
respond_to.
--webhook-url TEXT Notify this endpoint on APPROVAL_REQUESTED.
--webhook-secret-file FILE Read the shared secret from here instead of
$CTRLRUN_WEBHOOK_SECRET.
--allow-insecure-webhook Permit an http:// webhook url, loopback only.
--authority FILE Load the authority: section from a separate
YAML document (SPEC-v0.3 §8.3).
--identity-jwt Verify a bearer JWT (ctrlrun[identity]).
--identity-jwt-jwks-url TEXT Fetch keys from this JWKS (HTTPS).
--identity-jwt-public-key FILE A PEM public key file.
--identity-jwt-secret-file FILE
Read the HS* shared secret from here. Never a
flag value: a secret on a command line is in
every process listing on the host.
--identity-jwt-algorithms TEXT Repeatable, required. There is no default and
no wildcard.
--identity-jwt-issuer TEXT Matched exactly. Required.
--identity-jwt-audience TEXT Matched by membership. Required.
--identity-jwt-token-type TEXT Required. The token's typ, e.g. at+jwt. Pass
"" for "this issuer sets no typ".
--identity-jwt-header TEXT [default: authorization]
--identity-jwt-agent-claim TEXT
[default: sub]
--identity-jwt-user-claim TEXT Which claim is principal.user.
--identity-jwt-claim TEXT Repeatable: which verified claims reach the
receipt. An allow-list.
--identity-jwt-leeway FLOAT [default: 60.0]
--identity-jwt-jwks-min-refresh FLOAT
[default: 30.0]
--identity-jwt-http-timeout FLOAT
Bounds the JWKS fetch. Deliberately not
--upstream-timeout: the fetch runs on the
request thread before any decision, so the two
must not be one knob. [default: 5.0]
--otel Export one span per action (ctrlrun[otel]).
--otel-arguments Include argument values as span attributes.
Off by default: arguments carry customer
identifiers and amounts, and a trace backend
is not the receipt store.
--help Show this message and exit.
ctrlrun scan
Usage: ctrlrun scan [OPTIONS]
Report the consequential call sites and policy entries nothing is covering.
Reads Python source and a policy document as text. It never imports the tree,
never builds an action, never resolves a principal and never opens a store
(SPEC-scan §2.1, §9.2).
It is a finder and not a proof. Every run prints what it could not look at,
and a clean scan means nothing was found where it looked.
Exit codes: 0 nothing was found; 1 something was, including a suppressed
finding or a call whose name could not be resolved; 2 the scan could not run.
Options:
--path DIRECTORY The tree to read. Defaults to the working directory.
--policy FILE The policy to read. Defaults to ctrlrun.yaml beside the
tree, if there is one.
--exclude TEXT A glob, relative to the tree, not to read. Repeatable.
--vocabulary TEXT A file of verbs, one per line, replacing the built-in list.
With no value, print the list in force and exit.
--json Emit one ctrlrun.scan/v1 document.
--help Show this message and exit.
Next
- Exit codes: what each command’s exit status means.
- Resolve an AMBIGUOUS effect:
effects,resolveandinspectin use. - Get started · Why.