arizuko › reference › CLI commands
CLI commands
Every subcommand of the arizuko binary, grouped by concern. Each entry shows the exact signature, the flags flag.NewFlagSet registers, what state changes where, and a source link pointing at the dispatch site. Ground truth is cmd/arizuko/main.go; the dispatch map sits at main.go:54.
The CLI uses Go's standard flag package plus a hand-rolled positional dispatcher — no cobra. Top-level verb is os.Args[1]; subcommand verb (where applicable) is args[1] after the instance name. <instance> is the data-dir suffix; resolved via $ARIZUKO_DATA_DIR/arizuko_<name> or ${PREFIX:-/srv}/data/arizuko_<name> (main.go:146).
Index
- Instance lifecycle —
create,generate,run,status,pair - Config manifests —
export,apply,plan,get - Packages —
packages install|upgrade|remove|list,products list|apply - Operator chat & messaging —
chat,send,token - Groups & grants —
group list|add|rm|grant|ungrant|grants - Identities —
identity list|link|unlink - Invites —
invite create|list|revoke - Gates (rate limits) —
gate list|add|rm|enable|disable - Budget (cost caps) —
budget set|show folder|user - Network allowlist —
network allow|deny|list|resolve - Routes —
route list|add|rm - Secrets (folder & user) —
secret,user-secret
Instance lifecycle
arizuko create <name> [--product <product>]
Seed an instance data dir, write .env with a generated AUTH_SECRET and SECRETS_KEY, open store/, insert the default main group, set up its group folder, and seed default tasks. If --product is given, reads ant/examples/<product>/PRODUCT.md, prints the env checklist, and copies the product's skills/facts into the new group.
| Flag | Type | Default | Effect |
|---|---|---|---|
--product | string | "" | Product template name; looked up under $HostAppDir/ant/examples/<product>/PRODUCT.md. On miss, prints known products and exits non-zero. |
State touched: creates ${PREFIX:-/srv}/data/arizuko_<name>/, writes .env (mode 0600), makes routd's store, inserts the main group, calls container.SetupGroup for folder skeleton, seeds default tasks. Idempotent on .env (only written when missing).
arizuko create solo
arizuko create launch --product strategy
Source: cmd/arizuko/main.go:161
arizuko generate <instance>
Generate docker-compose.yml in the instance dir from compose.Generate. Atomic write via tempfile + rename; mode 0644.
State touched: writes <data-dir>/docker-compose.yml only.
arizuko generate krons
Source: cmd/arizuko/main.go:100
arizuko run <instance>
Generate the compose file (same path as generate), then docker compose -f <compose> up --remove-orphans. Foreground process; SIGINT propagates to the compose stack.
State touched: writes the compose file, then leaves long-lived docker state under control of docker.
arizuko run krons
Source: cmd/arizuko/main.go:89
arizuko status <instance>
docker compose ps against the instance compose file, then GET http://localhost:<APIPort>/v1/channels on the router with a 10s timeout. Prints registered channel name → URL pairs, or a "router API unreachable" / "no channels registered" line.
State touched: read-only. Requires docker-compose.yml to exist (will die with a "run 'arizuko generate' first" hint).
arizuko status krons
Source: cmd/arizuko/main.go:721
arizuko pair <instance> <service> [args...]
Run a one-shot pairing/admin shell against a compose service: docker compose -f <compose> run --rm <service> [args...]. Used for interactive setup of channel adapters (e.g. whapd QR pairing).
State touched: whatever the chosen service does. --rm removes the container on exit.
arizuko pair krons whapd
arizuko pair krons bskyd login --handle me.bsky.social
Source: cmd/arizuko/main.go:699
Config manifests
The cold-tier config of an instance — groups, acl, routes, web_routes, secrets, scheduled tasks, network rules, onboarding gates, proxyd routes — reads and writes as one YAML document. The same resreg engine that serves these resources over REST, MCP, and /openapi.json also drives export, apply, plan, and get, so the YAML shape matches the schema exactly. Spec specs/5/8-yaml-manifests.md.
arizuko export <instance> [output.yaml]
Dump the instance's cold-tier resources as YAML — one --- document per owning database. Keys sort deterministically (resources by name, rows by primary key), so re-exporting an unchanged store yields byte-identical output, which makes the file diffable in git. Each document ends with a checksum: line: a hash of the rows themselves, which is how apply later tells whether the store still holds what you exported. Writes to the named file if given; otherwise to stdout (the byte-count line goes to stderr so a redirect captures only YAML).
State touched: read-only.
arizuko export krons > krons-config.yaml
arizuko export krons krons-config.yaml
Source: cmd/arizuko/apply.go:69
arizuko apply <instance> <manifest.yaml> [--force] [--as-folder <folder>]
Replace the instance's cold-tier resources with the manifest's. For each resource named in the file, the engine deletes the rows the manifest covers and re-inserts the manifest's — one transaction per database. A resource absent from the manifest is left untouched; a resource present but empty is cleared. For a resource scoped to folders, only the folders the manifest mentions are touched, so a partial manifest never disturbs a group it does not name.
Two things can stop an apply before a single row is written. If the store no longer matches the checksum: the manifest was exported with, apply exits 2 and tells you to re-export — someone changed the config since you dumped it. And if any row names a folder that is not a group (neither declared in the file nor already present), apply refuses and names it: a typo'd folder would otherwise leave a rule attached to nothing. --force overrides the first check; nothing overrides the second.
The two databases have no shared transaction, so if the second one fails after the first committed, the first is put back exactly as it was — config only. Messages and memory written while the apply was running are untouched.
| Flag | Type | Default | Effect |
|---|---|---|---|
--force | bool | false | Skip the checksum check and apply anyway. Use when you mean to overwrite a change made since you exported. Does not skip the missing-folder check. |
--as-folder | string | — | Apply a one-folder manifest under a different folder name — how you copy a group's setup to a new group, or move one between instances. The file must describe exactly one folder, or this refuses rather than merging several. Needs --force, because a rewritten manifest can never match the target's checksum. |
State touched: rewrites every table named in the manifest, in one transaction. Deleting a group cascades to its web_routes and route_tokens (declared FKs, migrations 0068/0069) — the URL routes pinned to a removed group go with it.
arizuko export krons > krons.yaml
# edit krons.yaml
arizuko apply krons krons.yaml
arizuko apply krons krons.yaml --force
Source: cmd/arizuko/apply.go:29
arizuko plan <instance> <manifest.yaml>
Show what apply would change, without touching the DB. Prints one block per resource: + for rows the manifest adds, ~ for rows it updates, - for rows it removes. Secrets never mutate via apply, so they print as informational (N set (not applied)) rather than as deltas. A folder the manifest names but no group defines is reported here too, so you see the blocker and the diff in one run. If the manifest's checksum: doesn't match the store's, the last line says so — that's the same mismatch apply would reject without --force.
State touched: read-only.
arizuko export krons > krons.yaml
# edit krons.yaml
arizuko plan krons krons.yaml
Source: cmd/arizuko/apply.go:120
arizuko get <instance> <resource>
Emit one resource from the live store as a YAML fragment — the same shape apply accepts, so re-applying the fragment is a no-op. Use it to pull one table (say routes or web_routes) out of the store without exporting the whole config. Secret rows emit metadata only; the encrypted value never leaves the DB.
State touched: read-only.
arizuko get krons routes
arizuko get krons web_routes
Source: cmd/arizuko/apply.go:196
Full-instance backup
A config manifest carries what an instance is set up to do. An archive carries the instance: the same config, plus the encrypted secret values, the whole message history, the people still waiting to be let in, and every group's files — one tar you can move to another machine. Spec specs/5/8-yaml-manifests.md.
One thing deliberately stays behind: SECRETS_KEY. The encrypted secrets travel, the key that opens them does not — you carry that yourself, out of band. Restoring onto a machine whose key cannot decrypt them fails loudly instead of importing rubbish.
arizuko archive export <instance> [out.tar] [--quiesced]
Write the archive. Taken from a running instance it is a smear, not a snapshot: each part is read consistently, but a message can land between two reads, so the whole is a few seconds wide rather than one instant. That is usually fine, and the archive records which it is so a restore is never guessing. Stop the instance first and pass --quiesced when you need a true point-in-time image — the flag only stamps the label; it does not stop anything for you.
State touched: read-only.
arizuko archive export krons krons-backup.tar
arizuko archive export krons krons-backup.tar --quiesced
Source: cmd/arizuko/archive.go
arizuko archive apply <instance> <archive.tar> [--force] [--stopped]
Restore. Config goes in first, so every group exists before its files arrive; then message history is appended (re-running the same archive changes nothing already there); then each group's files are unpacked.
Unpacking a group's files while an agent is writing them would corrupt both, so the restore takes that folder's run slot first — the same slot an agent turn takes, so the two can never overlap. This means the instance must be up and runed reachable, or you pass --stopped to say it is down. An unreachable runed is a hard stop, never a warning: proceeding is the exact accident the slot exists to prevent.
Three parts hold credentials — chat links, invites, and pending setup links. They stay out by default, and even with --force go in only when the target has none of their own. Otherwise a restore would quietly re-activate a link someone had revoked, which is still sitting in a chat somewhere. A group whose files already exist is skipped for the same reason unless you pass --force; whatever was skipped is listed in the report.
| Flag | Type | Default | Effect |
|---|---|---|---|
--force | bool | false | Overwrite a group's existing files, and restore the credential-bearing parts onto an empty target. One flag for "yes, I mean it", not one per hazard. |
--stopped | bool | false | You assert the instance is down, so no run slot is claimed. Use this when restoring onto a machine where nothing is running. |
State touched: writes config, message history, secret values, onboarding admissions, and groups/<folder>/ trees.
arizuko archive apply krons krons-backup.tar --stopped
arizuko archive apply krons krons-backup.tar --force
Source: cmd/arizuko/archive.go
Packages
A package is a git source (or local directory) that ships any subset of asset kinds — a compose fragment (<name>.yml), a config manifest (<name>.yaml, carrying routes, grants, scheduled tasks, egress rules and web routes), skills (skills/<name>/) — as one versioned unit. Install writes an installed-package record to routd.db (source, resolved revision, owned identities, per-asset content hash) so upgrade and remove know exactly what the package owns. Full model on the packages reference. Spec specs/5/28. Dispatcher at main.go:81.
arizuko packages <instance> install <source>
Install a package from a source. A source is a git URL (git+https://…, git@…, github.com/org/pkg) shallow-cloned to a temp dir with its HEAD commit recorded as the revision, or a local directory used as-is (revision local). The package name is the source's last path segment (minus a trailing .git). Every *.yml and *.yaml asset copies into <data-dir>/services/; the manifest's rows apply live through the same engine as arizuko apply — one transaction with pre-image rollback, no restart; skills copy into <data-dir>/skills/<name>/. All-or-nothing: a source that carries no *.yml is refused, and a manifest that fails validation installs no row and leaves no file.
State touched: writes services/*.yml, opens routd.db and writes proxyd_routes / acl rows plus the installed-package record; may write skills/.
arizuko packages krons install github.com/kronael/arizuko-pkg-sentry
arizuko packages krons install ./my-local-package
Source: cmd/arizuko/packages.go:376
arizuko packages <instance> upgrade <name>
Re-install a recorded package's assets from its source. Before writing, it compares each asset's current on-disk content hash against the record; a locally edited (dirty) asset stops the upgrade with a list of what diverged — it never clobbers an operator's change. Assets the old record owned that the new source dropped are removed. On success the record's revision and hashes update.
State touched: rewrites the package's services/*.yml, updates the installed-package record. Refuses (no write) when a dirty asset is found.
arizuko packages krons upgrade arizuko-pkg-sentry
Source: cmd/arizuko/packages.go:432
arizuko packages <instance> remove <name>
Delete exactly the identities the installed-package record owns. Routes are withdrawn from proxyd_routes first (so no request is routed at a sidecar mid-teardown), then recorded grants come out of acl, then skills and fragment files are deleted, then the record is dropped. Falls back to deleting a bare <name>.yml for a catalog add that left no record.
State touched: deletes proxyd_routes / acl rows, services/*.yml, skills/, and the installed-package record.
arizuko packages krons remove arizuko-pkg-sentry
Source: cmd/arizuko/packages.go:486
arizuko packages <instance> list
List the bundled catalog fragments and their state: available (in the catalog, not enabled), enabled (present in services/), or enabled (local) (a fragment in services/ with no catalog twin).
State touched: read-only.
arizuko packages krons list
Source: cmd/arizuko/packages.go:331
After any of these, run arizuko generate <instance> to fold the fragment set into the compose file.
arizuko products <instance> list
Print the bundled catalog under $HOST_APP_DIR/ant/examples — one row per product, with the name, brand and tagline from its PRODUCT.md. These are the names --product accepts. A directory whose manifest won't parse is listed as broken rather than left out, so you can tell "this product doesn't ship" from "someone broke its manifest". Spec specs/5/21.
State touched: none — reads the catalog directory.
arizuko products krons list
Source: cmd/arizuko/products.go
arizuko products <instance> apply <folder>
Blend the ordered product mix declared in groups/<folder>/products.toml into that group. One [[product]] block per entry with a source; a relative source joins HOST_APP_DIR (so ant/examples/trip names the bundled corpus), a git URL is cloned and pinned to its revision. Each product's identity is the name in its PRODUCT.md. Blending is per payload kind — never a content merge — and a filename or settings-key collision refuses the whole apply before anything is written, as does any mcpServers key. Idempotent: an unchanged mix rewrites no byte and prints unchanged. A managed asset (a bundled skill) edited since the last apply is reported and skipped, never overwritten. Full table on the packages reference. Spec specs/5/28.
State touched: writes files under groups/<folder>/ and one installed_packages row per product, keyed (folder, name) — the only writer of a non-empty folder.
arizuko products krons apply main
Source: cmd/arizuko/products.go, blend engine container/blend.go
Operator chat & messaging
arizuko chat <instance>
Launch claude (Claude Code CLI) wired via socat to the instance's root MCP socket at <data-dir>/ipc/main/gated.sock. Writes a temporary mcpServers config pointing at socat STDIO UNIX-CONNECT:<sock> and execs claude --mcp-config <tmp>. Local-operator only — socket-fs access is the auth.
State touched: none on disk beyond a deleted-on-exit tempfile. Anything the agent does via MCP tools mutates the store as usual.
Prereqs: instance running (socket exists), claude and socat on $PATH.
arizuko chat krons
Source: cmd/arizuko/main.go:657
arizuko send <instance> <folder> [<message>] [--wait | --stream] [--stdin] [--topic <t>]
POST a message to a group's chat endpoint, optionally blocking until the agent's turn finishes. Resolves a web:<folder> token from route_tokens and reads WEB_HOST from .env; scheme is http for localhost/127.0.0.1, otherwise https. See specs/5/W-webhook-routes.md for the token model.
| Flag | Type | Default | Effect |
|---|---|---|---|
--wait | bool | false | After POST, poll /chat/<token>/<turn_id>?after=<seq> at 1s cadence, print frames, exit 0 on success / 1 on failed. |
--stream | bool | false | Same as --wait but subscribes to .../sse instead of polling. Exit codes: 0 success, 1 failed, 2 transport error. |
--stdin | bool | false | Read message body from stdin (trimmed) instead of the positional arg. |
--topic | string | auto-gen | Conversation thread id. Reuse the same value across calls to keep the agent in the same context. |
State touched: opens the instance store read-only to look up the chat token; everything else happens server-side via the /chat/<token>/ endpoint.
arizuko send krons main "hello from cli"
arizuko send krons main "what's the status?" --stream
echo "long body" | arizuko send krons main --stdin --wait
Source: cmd/arizuko/send.go:29
arizuko token <instance> <issue|list|revoke> ...
Manage the route tokens that back /chat/<token>/ visitor chat and /hook/<token> webhook ingest. Each token is one row in route_tokens mapping an opaque URL token to a JID and owner folder. issue mints a token for a web: or hook: JID and prints both the JID and the raw token (the token is shown once). list tabulates a folder's tokens. revoke deletes one by JID; pass <owner_folder> when the token was minted on behalf of a descendant or under a nested folder (the owner can diverge from the JID's folder), since the JID alone can't recover it.
| Subcommand | Form |
|---|---|
issue chat | arizuko token <instance> issue chat <folder> [<suffix>] |
issue webhook | arizuko token <instance> issue webhook <folder> <label> [<suffix>] |
list | arizuko token <instance> list <folder> |
revoke | arizuko token <instance> revoke <jid> [<owner_folder>] |
State touched: issue inserts a route_tokens row; revoke deletes one; list is read-only. issue and revoke write an audit row.
arizuko token krons issue chat support
arizuko token krons issue webhook eng github
arizuko token krons list support
arizuko token krons revoke web:support
Source: cmd/arizuko/token.go:20
Groups & grants
All group verbs share the same store and dispatch under cmd/arizuko/main.go:256.
arizuko group <instance> list
List all groups as tab-separated folder\tname.
State touched: read-only.
arizuko group krons list
Source: cmd/arizuko/main.go:268
arizuko group <instance> add <jid> <folder> [--product <name>]
Create a group bound to a channel JID. Folder is validated via groupfolder.IsValidFolder. Calls container.SetupGroup for the folder skeleton (optionally seeded from a product template under $HostAppDir/ant/examples/<product>/), seeds default tasks, inserts the group row, then adds a route room=<JidRoom(jid)> -> <folder>. For Discord guild channels (jid prefix discord: but not discord:dm/) the route is scoped to verb=mention so only mentions fire; other messages fall through to a catch-all #observe row.
| Flag | Type | Default | Effect |
|---|---|---|---|
--product | string | "" | Product template applied to this group (same set as arizuko create --product). On miss, errors with the expected PRODUCT.md path. |
State touched: filesystem (group skeleton), groups, routes, default-task seed.
arizuko group krons add whatsapp:120363042@g.us standup
arizuko group krons add "discord:guild/123/456" eng --product developer
Source: cmd/arizuko/main.go:275 (v0.40.6 added --product)
arizuko group <instance> rm <folder>
Delete the group row by folder via store.DeleteGroup. Does not remove the on-disk group directory or routes pointing at it; clean those up manually if needed.
State touched: groups table.
arizuko group krons rm standup
Source: cmd/arizuko/main.go:313
arizuko group <instance> grant <sub> <pattern>
Authorize sub on a scope. The literal pattern ** writes acl_membership(sub, role:operator) (the operator role's permissions live on the role, not duplicated per user); any other pattern writes an acl(principal=sub, action=admin, scope=pattern, effect=allow) row. Idempotent. See grants reference for syntax.
State touched: acl_membership (for **) or acl table.
arizuko group krons grant google:alice@example.com 'solo/**'
arizuko group krons grant telegram:42 'corp/eng/sre'
arizuko group krons grant google:operator@example.com '**' # operator role
Source: cmd/arizuko/main.go:347
arizuko group <instance> ungrant <sub> <pattern>
Reverse of grant. ** removes the operator-role membership edge; any other pattern deletes the matching acl row.
State touched: acl_membership (for **) or acl table.
arizuko group krons ungrant google:alice@example.com 'solo/**'
Source: cmd/arizuko/main.go:327
arizuko group <instance> grants [<sub>]
List grants. With no sub, lists all grants. With a sub, filters to that subject. Tab-separated SUB | PATTERN | GRANTED_AT.
State touched: read-only.
arizuko group krons grants
arizuko group krons grants google:alice@example.com
Source: cmd/arizuko/main.go:333
Identities
Identities unify multiple subject IDs (google:, telegram:, github:…) under one logical user. Dispatcher at main.go:550.
arizuko identity <instance> list
List all identities and the subs claimed by each. Columns: ID | NAME | CREATED_AT | SUBS (comma-joined).
State touched: read-only.
arizuko identity krons list
Source: cmd/arizuko/main.go:562
arizuko identity <instance> link <sub> [--name NAME] [--id ID]
Bind sub to an identity. With no --id, creates a new identity (display name is --name or, if empty, sub) and adds sub as its first claim. With --id, attaches sub to that existing identity.
| Flag | Type | Default | Effect |
|---|---|---|---|
--name | string | "" | Display name when creating a new identity. Ignored if --id is set. |
--id | string | "" | Existing identity ID to attach sub to; bypasses creation. |
State touched: identities, identity_subs.
arizuko identity krons link google:alice@example.com --name Alice
arizuko identity krons link telegram:42 --id id_a1b2c3
Source: cmd/arizuko/main.go:566
arizuko identity <instance> unlink <sub>
Remove the claim row for sub. Prints "no claim to remove" if there was none.
State touched: identity_subs.
arizuko identity krons unlink telegram:42
Source: cmd/arizuko/main.go:577
Invites
Onboarding tokens consumed by onbod's invite landing. Dispatcher at main.go:473.
arizuko invite <instance> create <target_glob> [--max-uses N] [--expires DURATION]
Mint an invite token whose redemption grants the user the given target_glob pattern. Prints token, target, max-uses, optional expiry.
| Flag | Type | Default | Effect |
|---|---|---|---|
--max-uses | int | 1 | Maximum redemptions. Rejected if < 1. |
--expires | duration | 0 (no expiry) | Time-from-now after which the token is dead. Parsed by time.ParseDuration (24h, 72h30m, …). |
State touched: invites table; issued_by_sub is set to the literal "cli".
arizuko invite krons create 'solo/**' --max-uses 1 --expires 72h
arizuko invite krons create 'corp/eng/**' --max-uses 5
Source: cmd/arizuko/main.go:485
arizuko invite <instance> list [--issued-by SUB]
List invites. Columns: TOKEN | TARGET_GLOB | ISSUED_BY | ISSUED_AT | EXPIRES_AT | USED (where USED is used_count/max_uses).
| Flag | Type | Default | Effect |
|---|---|---|---|
--issued-by | string | "" | Filter to invites issued by a specific subject. Empty = all. |
State touched: read-only.
arizuko invite krons list
arizuko invite krons list --issued-by cli
Source: cmd/arizuko/main.go:512
arizuko invite <instance> revoke <token>
Revoke a token by ID. Future redemption attempts fail.
State touched: invites row marked revoked.
arizuko invite krons revoke inv_abc123
Source: cmd/arizuko/main.go:538
Gates (rate limits)
Per-spec daily limits enforced inside onbod (the admission daemon). Dispatcher at main.go:402.
arizuko gate <instance> list
List gates as GATE | LIMIT/DAY | ENABLED. Prints no gates if empty.
State touched: read-only.
arizuko gate krons list
Source: cmd/arizuko/main.go:414
arizuko gate <instance> add <spec> <N>/day
Upsert a gate at the given daily limit. Limit string accepts an optional /day suffix (stripped); must parse as a positive integer.
State touched: gates table.
arizuko gate krons add solo/inbox 200/day
arizuko gate krons add 'corp/eng/**' 1000
Source: cmd/arizuko/main.go:434
arizuko gate <instance> rm <spec>
Delete a gate row by spec.
State touched: gates table.
arizuko gate krons rm solo/inbox
Source: cmd/arizuko/main.go:447
arizuko gate <instance> enable <spec>
Flip enabled to true on the row.
State touched: gates table.
arizuko gate krons enable solo/inbox
Source: cmd/arizuko/main.go:454
arizuko gate <instance> disable <spec>
Flip enabled to false on the row. The row stays so the spec/limit survives re-enable.
State touched: gates table.
arizuko gate krons disable solo/inbox
Source: cmd/arizuko/main.go:461
Budget (cost caps)
Per-folder and per-user daily spend caps in cents, stored on groups.cost_cap_cents_per_day and user_profiles.cost_cap_cents_per_day. The cap is arizuko’s policy; the model gateway enforces it. routd’s pre-spawn gate pushes each cap to the gateway as a one-day budget and refuses the turn when the gateway’s meter is at it. budget show prints the cap, not the spend — the spend belongs to the gateway, and reading it needs a master key this CLI does not hold; see /dash/usage/. Without a gateway nothing enforces a cap, which routd logs at ERROR. Spec 6/39. Dispatcher at budget.go:18.
arizuko budget <instance> set <folder|user> <name|sub> --daily N
Set a daily cap (in cents) on a folder or user. --daily 0 removes the cap (uncapped). Negative values are rejected.
| Flag | Type | Default | Effect |
|---|---|---|---|
--daily | int | required | Daily cap in cents. 0 = uncapped (cap row removed). |
State touched: groups.cost_cap_cents_per_day (folder scope) or auth_users.cost_cap_cents_per_day (user scope).
arizuko budget krons set folder corp/eng --daily 5000
arizuko budget krons set user google:alice@example.com --daily 1000
arizuko budget krons set folder solo/inbox --daily 0 # uncapped
Source: cmd/arizuko/budget.go:30
arizuko budget <instance> show <folder|user> <name|sub>
Print the cap, today's spend, remaining budget, and a status line (ok, WARN at ≥80%, EXHAUSTED when turns will be refused). Tab-aligned key/value table.
State touched: read-only.
arizuko budget krons show folder corp/eng
arizuko budget krons show user google:alice@example.com
Source: cmd/arizuko/budget.go:43
Network allowlist
Per-folder egress rules. Each spawn’s own egress proxy is started with the resolved list baked in. Walks the folder ancestry on resolve. Dispatcher at network.go:12.
arizuko network <instance> allow <folder> <target>
Add an allow rule binding a folder to a hostname (or other target form supported by store.AddNetworkRule). created_by is set to the literal "cli".
State touched: network_rules table.
arizuko network krons allow main api.github.com
arizuko network krons allow corp/eng api.openai.com
Source: cmd/arizuko/network.go:24
arizuko network <instance> deny <folder> <target>
Remove a previously-added allow rule. Naming preserves the operator-mental-model (allow + deny as paired verbs); under the hood it's a row delete via store.RemoveNetworkRule.
State touched: network_rules table.
arizuko network krons deny main api.github.com
Source: cmd/arizuko/network.go:32
arizuko network <instance> list [<folder>]
List rules. Without <folder>, lists all. With a folder, lists that folder's own rows (not inherited ones — use resolve for that). Columns: FOLDER | TARGET | CREATED_AT | CREATED_BY (root rows render as (root)).
State touched: read-only.
arizuko network krons list
arizuko network krons list corp/eng
Source: cmd/arizuko/network.go:40
arizuko network <instance> resolve <folder>
Print the fully resolved allowlist for a folder — walks ancestry, dedupes, includes the root seeds (anthropic.com, api.anthropic.com, from routd/migrations/0005-network-rules.sql). One target per line. Useful for verifying what a folder’s proxy will accept.
State touched: read-only.
arizuko network krons resolve corp/eng/sre
Source: cmd/arizuko/network.go:66
Routes
The route table maps inbound messages to group folders. Each row is a seq (priority, lower wins), a match expression over message attributes, and a target folder. arizuko group add writes a route for you; use route to add the catch-all and cross-source rules by hand. Routes share their store with acl: both are routd's, on the instance's store server or in routd.db. Writes are audit-free, mirroring the grant path. For bulk or GitOps-style edits, declare routes in a manifest and arizuko apply. Dispatcher at route.go:20.
arizuko route <instance> list
List every route ordered by seq then id. Columns: ID | SEQ | MATCH | TARGET. An empty match renders as * (catch-all). Prints no routes if empty.
State touched: read-only.
arizuko route krons list
Source: cmd/arizuko/route.go:29
arizuko route <instance> add <match> <target> [--seq N]
Add a route binding a match expression to a target folder. match is a space-separated set of key=value predicates (e.g. platform=telegram, verb=mention, chat_jid=hook:*/sentry/*); * or an empty string is the catch-all and is stored as an empty match. Prints the new id.
| Flag | Type | Default | Effect |
|---|---|---|---|
--seq | int | 0 | Match priority; lower wins. Put it before the positionals. |
State touched: routes table (audit-free PutRouteRow).
arizuko route krons add 'platform=telegram' supermarket
arizuko route krons add '*' corp/intake --seq 10
arizuko route krons add 'chat_jid=hook:*/sentry/*' corp/eng/sre --seq -10
Source: cmd/arizuko/route.go:35
arizuko route <instance> rm <id>
Delete a route by id (from route list). Errors with no route <id> if it doesn't exist.
State touched: routes table row delete (audit-free DeleteRouteRow).
arizuko route krons rm 7
Source: cmd/arizuko/route.go:46
Secrets (folder & user)
Folder-scoped and user-scoped secrets backing the secret-broker model (see specs/5/14-credentials.md). Keys must match ^[A-Z][A-Z0-9_]*$ (validated by keyValid at secret.go:132).
secrets table, split by scope_kind (folder or user). The same rows back the REST and MCP secret surface (spec 5/13). Values are encrypted at rest; list shows keys, never values.arizuko secret <instance> set <folder> KEY --value V
Store a folder-scoped capability secret. --value is required; empty values rejected. Key is validated against the uppercase ENV-style pattern. The four model keys (ANTHROPIC_API_KEY, CLAUDE_CODE_OAUTH_TOKEN, OPENAI_API_KEY, CODEX_API_KEY) are rejected at folder scope — they belong to the host .env or to a user at /dash/me/env.
| Flag | Type | Default | Effect |
|---|---|---|---|
--value | string | "" | Secret value. Required, must be non-empty. |
State touched: secrets table, scope_kind = folder.
arizuko secret krons set corp/eng GITHUB_TOKEN --value ghp_xxxxxxxxxxxx
arizuko secret krons set main CF_API_TOKEN --value cf_xxxxxxxx
Source: cmd/arizuko/secret.go:28
arizuko secret <instance> list <folder>
List keys (not values) for a folder. Columns: KEY | CREATED_AT. Prints no secrets if empty.
State touched: read-only.
arizuko secret krons list corp/eng
Source: cmd/arizuko/secret.go:38
arizuko secret <instance> delete <folder> KEY
Delete one folder-scoped key.
State touched: secrets table row delete.
arizuko secret krons delete corp/eng GITHUB_TOKEN
Source: cmd/arizuko/secret.go:43
arizuko user-secret <instance> set <user_sub> KEY --value V
Operator fallback for setting a user-scoped secret on behalf of a user who hasn't logged in via /dash/me/secrets yet. Same key validation as secret set.
| Flag | Type | Default | Effect |
|---|---|---|---|
--value | string | "" | Secret value. Required, must be non-empty. |
State touched: secrets table, scope_kind = user.
arizuko user-secret krons set google:alice@example.com GITHUB_TOKEN --value ghp_xxx
Source: cmd/arizuko/secret.go:67
arizuko user-secret <instance> list <user_sub>
List keys for one user sub. Columns: KEY | CREATED_AT.
State touched: read-only.
arizuko user-secret krons list google:alice@example.com
Source: cmd/arizuko/secret.go:77
arizuko user-secret <instance> delete <user_sub> KEY
Delete one user-scoped key.
State touched: secrets table row delete.
arizuko user-secret krons delete google:alice@example.com GITHUB_TOKEN
Source: cmd/arizuko/secret.go:82
See also
- reference index
- env vars — what the daemons themselves read
- MCP tools — the in-container surface the agent calls (often pairs with these CLI verbs)
- grants syntax — pattern language used by
group grantandinvite create cmd/arizuko/— source of truth