| name | zerion-agent-management |
|---|---|
| description | Manage Zerion agent tokens and security policies — the primitives for autonomous trading and signing. Create / list / use / revoke agent tokens; create / list / show / delete policies (chain locks, allowlists, transfer/approval gates, expiry). Use whenever the user asks to set up an agent token, configure a policy, or enable autonomous trading. Required by `zerion-trading` and `zerion-sign`. |
| license | MIT |
| allowed-tools | Bash |
Agent tokens authorize the CLI to sign transactions on behalf of a wallet without a passphrase prompt. Policies attached to a token scope what the token can do (chains, allowlist, deny rules, expiry). This is the foundation for safe autonomous trading and off-chain signing.
If a zerion command fails with command not found, install once:
npm install -g zerion-cliRequires Node.js ≥ 20. For auth see the zerion umbrella skill. To execute trades after setup → zerion-trading. To sign messages/typed-data → zerion-sign.
- "Create an agent token"
- "Set up autonomous trading"
- "Restrict the bot to chain X / address Y"
- "Block transfers" / "block approvals" / "expire the token in N days"
- "Switch which agent token is active"
- "Revoke a token"
| Operation | Type | Notes |
|---|---|---|
agent list-tokens, agent list-policies, agent show-policy, agent use-token |
Agent | Read-only or config-only. Safe autonomously. |
agent create-token (default) |
Manual | Interactive passphrase prompt. Humans run it. |
agent create-token --passphrase-file <path> |
Agent-capable | Reads passphrase from a chmod 600 file. For CI / headless / scripted setup once the file is provisioned by a human or secrets manager. |
agent revoke-token, agent create-policy, agent delete-policy |
Manual | Require passphrase or confirmation. Humans must run these directly. |
zerion agent list-tokens # Tokens, attached policies, active flag, wallet binding
zerion agent list-policies # All policies with rules summary
zerion agent show-policy <id> # Full policy details
zerion agent use-token --wallet <wallet> # Switch the active token (config edit, no passphrase)The default flow is human-interactive. agent create-token also has a non-interactive variant (--passphrase-file) for automation once the passphrase file is provisioned. Everything else in this section requires a human.
# Interactive policy picker (recommended)
zerion agent create-token --name <bot> --wallet <wallet>
# Attach an existing policy by ID
zerion agent create-token --name <bot> --wallet <wallet> --policy <id>
# Multiple policies (AND semantics — all must pass)
zerion agent create-token --name <bot> --wallet <wallet> --policy <id1>,<id2>The token is auto-saved to ~/.zerion/config.json under agentTokens and (if no token was active before) becomes the default. Trading commands (zerion-trading) and signing commands (zerion-sign) read it from config.
--passphrase-file <path> takes a path to a plain-text file whose entire contents are the wallet passphrase (the same string a human would type at the TTY prompt). The CLI reads the file once and uses its contents to unlock the keystore. Nothing else lives in the file — no JSON, no key=value, no header.
For CI, headless servers, or scripted agent setup, write the passphrase to such a file instead of typing it:
# Write the passphrase to a file readable only by you
umask 077 # ensure new files default to 0600
printf '%s' "$ZERION_PASSPHRASE" > ~/.zerion-pass
chmod 600 ~/.zerion-pass # required — refused if looser
# Create the token non-interactively
zerion agent create-token \
--name bot --wallet my-agent \
--policy <id> \
--passphrase-file ~/.zerion-pass
# Clean up immediately
shred -u ~/.zerion-pass 2>/dev/null || rm -f ~/.zerion-passFor ephemeral storage (recommended on Linux), use a tmpfs mount instead of $HOME:
# Linux only — /run is tmpfs (RAM-only, gone on reboot)
sudo install -d -m 0700 -o "$USER" /run/zerion
printf '%s' "$ZERION_PASSPHRASE" > /run/zerion/pass && chmod 600 /run/zerion/pass
zerion agent create-token ... --passphrase-file /run/zerion/passOn macOS, use /private/tmp/<your-user>/... or a per-app dir under ~/Library/Caches/. macOS does not ship a user-writable /run.
Plain UTF-8 text. The entire file (minus exactly one optional trailing \n or \r\n) is treated as the passphrase.
| Rule | Reason |
|---|---|
| Content = raw passphrase bytes only | No JSON, no key=value, no comments, no quotes. Anything in the file is part of the passphrase. |
One trailing \n or \r\n stripped |
So echo "pass" > file works as expected. Additional newlines are kept. |
| Leading / trailing spaces inside the passphrase are preserved | Passphrases may legitimately contain them. CLI does not .trim(). |
| UTF-8 encoded | Read via readFileSync(path, "utf8"). Non-UTF-8 bytes become replacement chars. |
| Non-empty | Empty file or newline-only file → rejected. |
Mode 0600 (POSIX) |
Refused otherwise — see Rules below. |
| Regular file, owned by current uid | Symlinks-to-files are followed; the target must still pass perm + ownership checks. |
Examples (file bytes → passphrase used by CLI):
| Command | File bytes | Passphrase result |
|---|---|---|
printf '%s' 'hunter2' > f |
hunter2 |
hunter2 ✅ |
printf '%s\n' 'hunter2' > f |
hunter2\n |
hunter2 ✅ |
echo 'hunter2' > f |
hunter2\n |
hunter2 ✅ |
echo '"hunter2"' > f |
"hunter2"\n |
"hunter2" (quotes included!) ❌ |
echo ' spaces ' > f |
spaces \n |
spaces (spaces kept) ✅ |
printf '' > f |
(empty) | rejected ❌ |
printf '\n' > f |
\n |
rejected ❌ |
Canonical form — no trailing newline, no surprises:
umask 077
printf '%s' 'YOUR-PASSPHRASE' > ~/.zerion-pass
chmod 600 ~/.zerion-passVerify before using:
wc -c ~/.zerion-pass # byte count == passphrase length
xxd ~/.zerion-pass | head # eyeball raw bytes — no BOM, no quotes, no CRLF- File must be mode
0600(owner read/write only). Any group/other bits → CLI refuses withpassphrase_file_error. - File must be owned by the current uid (POSIX). Reading another user's file (e.g. via symlink) is refused. Matches SSH
IdentityFilebehavior. - Trailing newline (
\nor\r\n) is stripped; leading/trailing spaces inside the passphrase are preserved. - Empty file is rejected.
- Permission and ownership checks are skipped on Windows (POSIX mode bits and uid not meaningful there) — use NTFS ACLs to restrict access instead.
Recommended patterns:
| Environment | Source | Notes |
|---|---|---|
| Local dev | ~/.zerion-pass (chmod 600) |
Delete after use. |
| Docker | Bind-mount a tmpfs file | --tmpfs /run/zerion:mode=0700 then write passphrase inside. |
| Kubernetes | Mount a Secret as a file |
Default mount mode is 0644 — set defaultMode: 0600 in the volume spec. |
| GitHub Actions | Write ${{ secrets.X }} to a temp file, chmod 600, then run |
Cleanup is automatic at job end. |
| HashiCorp Vault | vault agent template renders to a 0600 file |
Renew & rotate centrally. |
Threat model: same as an SSH private key on disk. Anyone with active-session read access to the file can unlock the keystore. Keep the file path off shared filesystems, out of git, out of process listings. Argv-passed passphrases (--passphrase <value>) are not supported because they leak to ps aux, shell history, and CI logs.
--passphrase-file only affects agent create-token for now. wallet create, wallet import, and other passphrase-gated commands still require an interactive TTY.
zerion agent revoke-token --name <bot>
zerion agent revoke-token --id <id>A policy is a set of rules a token must pass before signing. At least one rule required.
# Chain lock — restrict to specific chains
zerion agent create-policy --name safe-base --chains base,arbitrum
zerion agent create-policy --name monad-only --chains monad
# Expiry — token deactivates after duration (e.g. 24h, 7d)
zerion agent create-policy --name short-lived --expires 7d
# Block raw native transfers (ETH/SOL send command)
zerion agent create-policy --name no-transfers --deny-transfers
# Block ERC-20 approvals (prevents allowance grants)
zerion agent create-policy --name no-approvals --deny-approvals
# Allowlist — only allow interaction with specific contract addresses
zerion agent create-policy --name dex-only --allowlist 0xUniRouter,0xCowSwap
# Combined rules (AND semantics)
zerion agent create-policy --name strict \
--chains base \
--expires 7d \
--deny-transfers \
--deny-approvalszerion agent delete-policy <id>Tokens that referenced the deleted policy will no longer pass that rule check.
| Flag | Effect |
|---|---|
--chains <list> |
Restrict to listed chains (comma-separated) |
--expires <duration> |
Token deactivates after duration. Format: <n>h, <n>d (e.g. 24h, 7d) |
--deny-transfers |
Block raw native transfers (zerion send of native asset) |
--deny-approvals |
Block ERC-20 approve calls |
--allowlist <addrs> |
Only allow interaction with listed contract addresses (comma-separated) |
Policies execute as locally-spawned scripts (policies/*.mjs in the CLI repo). They run on every signing attempt before the transaction is built.
# 1. Create wallet (manual — see zerion-wallet skill)
zerion wallet create --name agent-bot
# 2. Create a tight policy
zerion agent create-policy --name swap-only \
--chains base,arbitrum \
--expires 30d \
--deny-transfers \
--allowlist 0xUniswapRouter,0x1inchRouter
# 3. Create the agent token bound to that policy
zerion agent create-token --name agent-bot \
--wallet agent-bot \
--policy <swap-only-id>
# Now zerion-trading and zerion-sign work autonomously| Code | Cause | Fix |
|---|---|---|
no_agent_token |
No active token for wallet | agent create-token --wallet <wallet> |
agent_token_expired |
Policy --expires lapsed |
Create a fresh token |
policy_denied |
Action blocked by policy | agent show-policy <id> to see rules; revise or use a different token |
policy_not_found |
Policy ID doesn't exist | agent list-policies to find valid IDs |
policy_no_rules |
create-policy with no flags |
Add at least one rule (--chains, --expires, --deny-*, --allowlist) |
token_name_exists |
Duplicate --name |
Choose another name or agent revoke-token --name <bot> first |
passphrase_file_error |
--passphrase-file path missing, wrong perms, or empty |
chmod 600 <path>; ensure file exists and is non-empty |