agentjail ships as two binaries: agentjail (the management CLI) and
agentjail-hook (called automatically by the agent’s PreToolUse hook). This
page documents every subcommand of the management CLI, plus how to invoke the
hook manually for testing.
agentjail version
Prints the installed version and exits.
agentjail version
Example output:
agentjail v1.2.0
agentjail help
Prints a summary of every available subcommand.
agentjail help
agentjail claude / agentjail run
Launches your coding agent inside the agentjail OS-native sandbox (Seatbelt on
macOS, Landlock on Linux) with LLM-traffic capture on. This is the recommended
way to run an agent day to day. agentjail claude is a dedicated alias; other
agents launch through agentjail run -- <cmd>.
agentjail claude # Claude Code, shielded (default)
agentjail run -- codex # Codex, shielded
agentjail run -- cursor # Cursor, shielded
agentjail claude --no-sandbox # hook-only policy, no OS sandbox
agentjail claude --tunnel # capture + enforce ALL traffic via the tunnel
agentjail run --tunnel --require-tunnel -- codex
# refuse to run if the tunnel cannot start
agentjail run --credential cluster-dev -- codex
# deliver one exact credential to the session
agentjail run --verbose -- codex # mirror private startup diagnostics to stderr
Extra arguments pass straight through to the agent (e.g. agentjail claude -p "..."). agentjail claude is shorthand for agentjail run -- claude; use
agentjail run -- <cmd> to shield an arbitrary command.
The separator is optional: agentjail run codex and agentjail run -- codex
both work. Put AgentJail launch options before the child command. Use an explicit
separator to forward child help: agentjail run -- codex --help.
agentjail run help, agentjail run --help, and agentjail help run show
AgentJail launch help. All command help shares the CLI styling, with plain output
when piped or color is disabled.
For a shielded Codex launch, put the native bypass flag first:
agentjail run -- codex --dangerously-bypass-approvals-and-sandbox
agentjail run -- codex --yolo
AgentJail keeps Codex at danger-full-access while retaining user-reviewed
execpolicy-rule approvals for AgentJail policy asks. Other Codex approval
categories remain disabled. This is a custom approval configuration, not
Codex’s native YOLO permission setting; AgentJail’s outer shield remains active.
An explicit agentjail run --no-sandbox -- codex --yolo preserves Codex’s native
bypass arguments and provides only the weaker hook-based policy layer.
| Flag | Default | Description |
|---|---|---|
--no-sandbox | off | Run hook-only, without the OS sandbox. |
--tunnel | off | Route all traffic through the transparent tunnel (MITM + per-host policy, HTTP/2 + gRPC). |
--require-tunnel | off | Fail closed instead of falling back when the transparent tunnel is unavailable. AGENTJAIL_REQUIRE_TUNNEL=1 is the automation equivalent. |
--credential <ID> | none | Deliver the exact stored credential ID to the shielded session. Repeat to deliver more than one record. |
--no-provider-gateway | off | Disable the base-URL LLM capture gateway. |
--verbose | off | Mirror structured shield startup diagnostics to stderr. |
By default the LLM provider call is captured through the base-URL capture gateway (on macOS with no system extension). See the OS-native sandbox for the full network model.
Direct agentjail run -- <cmd> launches keep the transparent tunnel opt-in.
The wrappers installed by agentjail install --with-path-shim use the tunnel by
default for Claude Code, Codex, and Cursor while preserving child arguments.
Use --require-tunnel when fallback would invalidate a test or release claim.
Routine startup prints one to three lines. Each shielded launch also writes
structured diagnostics under ~/.agentjail/logs/, retaining the newest 10
files. The directory is mode 0700, and each log is mode 0600.
agentjail install
Installs the hook and starts the daemon. With no flags, agentjail install
auto-detects every coding agent present on the machine (Claude Code, Codex,
Cursor) and presents an interactive multi-select picker: all detected agents
start checked; press Space to uncheck, Enter to confirm. Without a TTY (CI),
all detected agents are wired automatically.
agentjail install # auto-detect + interactive picker
agentjail install --for claude-code # wire a single specific agent
agentjail install --all # non-interactive, wire all detected agents
| Flag | Description |
|---|---|
--for <agent> | Wire a single agent: claude-code, codex, or cursor. |
--all | Non-interactive; wire every detected agent. |
--allow-unsupported | Deprecated no-op. Linux is fully supported (systemd user service); kept only for old CI scripts. |
--with-path-shim | Standalone action: installs wrappers for claude, codex, and Cursor’s agent command plus an opt-in shell-rc block, so those commands run shielded through the transparent tunnel. Child arguments pass through, and the choice survives reinstall and update. |
--with-apparmor | Standalone action (Linux): loads the scoped userns AppArmor profile used by the sandbox (needs root once). Consent-gated - prompts for confirmation unless --yes or AGENTJAIL_ASSUME_YES=1 is set. |
Platform support: agentjail install works on macOS and Linux. On Linux,
the daemon runs as a systemd user service instead of a launchd plist.
MCP trust-on-install: the installer seeds mcp.allowed in policy.yaml
from the MCP servers already configured in your agents (Claude/Codex/Cursor),
so existing servers like claude-mem or context7 keep working immediately.
agentjail uninstall
Removes the hook and daemon.
agentjail uninstall # full teardown: unhook all agents, stop daemon, remove ~/.agentjail
agentjail uninstall --for claude-code # single-agent only; daemon + ~/.agentjail untouched
agentjail uninstall --path-shim-only # remove just the PATH shim; hook + daemon untouched
agentjail uninstall --keep-credentials # full teardown, but preserve the credential vault
agentjail uninstall --force # full teardown even if the daemon can't be verified stopped
| Flag | Description |
|---|---|
--path-shim-only | Removes only the --with-path-shim binary and its shell-rc block. Leaves the hook, daemon, and ~/.agentjail untouched. |
--keep-credentials | On a full teardown, preserves secrets.key and the secrets/ directory (the credential vault) instead of wiping them with the rest of ~/.agentjail. The old hidden --keep-secrets alias still works but is deprecated. |
--force | A full teardown normally aborts if the daemon can’t be verified stopped, because a still-running daemon’s hookwatch re-injects the hook as fast as uninstall removes it. --force proceeds anyway, leaving hooks re-injected. |
Without --force, an unstoppable daemon leaves your install fully intact - the
teardown aborts before touching anything and tells you to pkill the daemon
and re-run.
agentjail status
Prints detection and hook state for every agent, and whether the daemon is running.
agentjail status
agentjail doctor
Diagnoses your setup - daemon health, hook wiring, the supervisor restart
invariant, network posture, and (on Ubuntu) unprivileged-userns availability -
and prints the effective value of every network knob and where it came from
(CLI flag > env var > policy.yaml > default). It also compares the installed
CLI version with the running daemon, so a stale process is reported as a
repairable failure instead of healthy liveness.
agentjail doctor # diagnose
agentjail doctor --fix # repair what it can (dead daemon, dangling shim,
# stale service unit), then re-check
agentjail try
Evaluates any action against the live policy and reports the verdict without executing anything. No agent session required.
agentjail try "cat ~/.ssh/id_rsa" # ✗ DENY
agentjail try "git status" # ✓ ALLOW
agentjail try # interactive: type commands, Ctrl-D to quit
agentjail logs
Tails and filters the daemon audit log.
agentjail logs
agentjail logs --action=deny --since=1h
| Flag | Description |
|---|---|
--action=<allow|ask|deny> | Show only entries with this verdict. |
--since=<duration> | Limit to entries within the last duration (e.g. 1h, 30m). |
-v | Adds a secondary summary line per entry showing command/file_path, reason, and session_id. |
Example output:
TIME ACTION TOOL IMPACT
19:24:01 DENY Bash would touch sensitive path via Bash
↳ printf 'null' > ~/.ssh/id_rsa
🟢 4 allow · 🔴 1 deny · 🟡 0 ask
agentjail cost
Summarizes indexed local usage from Claude Code, Codex, and OpenCode by project and model. Cursor remains supported for sandboxing and policy enforcement, but it is not a cost-report source. The daemon incrementally maintains a content-free projection in the existing AgentJail SQLite store. The command reads that small projection and never falls back to rescanning local transcripts.
agentjail cost
agentjail cost --period 30d
agentjail cost --project ./my-repo
agentjail cost --json
| Flag | Default | Description |
|---|---|---|
--period <duration> | 7d | Report window, up to 90 days. Accepts values such as 24h, 7d, and 30d. |
--project <path> | all projects | Filter the displayed report to one project. Budget checks still use all collected sessions. |
--json | off | Print the typed report and budget alerts as JSON. |
--db <path> | ~/.agentjail/agentjail.db | Read a specific AgentJail SQLite store. |
Optional budgets live under cost in ~/.agentjail/policy.yaml:
cost:
daily_budget: 20
alert_threshold: 0.8
project_budgets:
~/src/agentjail: 8
The first v1.8.0 daemon start performs one resumable background backfill. The command reports a building index until that succeeds, and warns when the last refresh is older than 26 hours. Pricing remains local through the bundled Gryph catalog. No transcript content is copied into the index, and cost maintenance never affects policy enforcement.
agentjail ui
Opens the local, loopback-only web dashboard backed by
~/.agentjail/agentjail.db. It has a Monitor tab (every policy decision,
with action/tool/rule/session filters and session replay), a Network tab
(captured LLM requests and responses, plus tunnel traffic), and a Cost tab
for the same local report exposed by agentjail cost.
agentjail ui
Policy status is read-only by default; pass --edit-policy only when you want
enable/disable controls in the UI.
On macOS, shielded sessions start the loopback UI on demand and show a clickable
UI link in the persistent status line when the server is reachable. Manual
agentjail ui startup remains available on both macOS and Linux.
agentjail monitor
Reports what policy would have blocked, without changing enforcement. Reads
recorded decisions from ~/.agentjail/agentjail.db and groups them by rule,
verdict, and tool. See ADR 0091-monitor-mode-tools.
agentjail monitor # what would have blocked in the last 24h
agentjail monitor --since=7d # widen the window
agentjail monitor --json # machine-readable output
| Flag | Default | Description |
|---|---|---|
--db <path> | ~/.agentjail/agentjail.db | Path to the SQLite event store. |
--policy <path> | ~/.agentjail/policy.yaml | Path to policy.yaml, used to frame the report (monitor mode vs. enforce mode). |
--since <duration> | 24h | Time range to report over (e.g. 1h, 7d, 30m); 0 for all time. |
--json | off | Output as JSON. |
agentjail stats
Summarizes activity from the local SQLite decision store. Totals use the final observed outcome, so an action allowed by policy but blocked by the OS sandbox counts as blocked. The ranked deny table reports canonical policy denies.
agentjail stats # all recorded activity
agentjail stats --since 24h # recent activity
agentjail stats --top 20 # show more ranked rows
agentjail stats --json # typed machine-readable report
The report includes sessions, active days, allowed/asked/blocked totals, per-agent counts, policy deny rules, audit event counts, latency percentiles, and days when the shield activated but no decisions were recorded.
| Flag | Default | Description |
|---|---|---|
--db <path> | ~/.agentjail/agentjail.db | Path to the SQLite event store. |
--since <duration> | 0 | Time range to report over, such as 24h, 7d, or 30m; 0 means all time. |
--top <count> | 10 | Maximum rows shown in each ranked table. |
--json | off | Output the typed stats report as JSON. |
agentjail sessions
Lists recorded agent sessions from the local event store.
agentjail sessions list
agentjail sessions list --active --json
agentjail sessions list --since 7d
| Flag | Default | Description |
|---|---|---|
--db <path> | ~/.agentjail/agentjail.db | Path to the SQLite event store. |
--active | off | Show only sessions with a live daemon connection. |
--since <duration> | 24h | Only sessions active within this duration (e.g. 1h, 7d, 30m); 0 for all time. |
--json | off | Output as a JSON array. |
agentjail replay
Replays the recorded decisions for a single session, in a Bubble Tea TUI by default.
agentjail replay --list # list sessions to replay
agentjail replay --session <session_id>
agentjail replay --session <session_id> --follow # follow new decisions live
agentjail replay --session <session_id> --basic # plain-text output, no TUI
| Flag | Description |
|---|---|
--session <id> | Session ID to replay. Required unless --list is set. |
--list | List available sessions instead of replaying one. |
--follow | Follow new decisions for the session as they arrive. |
--verbose | Include redacted tool_input in the output. |
--basic | Plain-text output instead of the TUI. |
--no-color | Disable ANSI colors. |
--db <path> | Path to the SQLite event store (defaults to ~/.agentjail/agentjail.db). |
agentjail mcp
Manages the MCP server allowlist. Changes hot-reload the daemon immediately.
agentjail mcp list # show current allowed + blocked servers
agentjail mcp allow claude-mem # trust a server
agentjail mcp block my-payment-bot # block a server
The install command auto-seeds the allowlist from MCP servers already configured
in Claude/Codex/Cursor. The default blocklist (*stripe*, *payment*,
*billing*, *twilio*, *sendgrid*) always wins, even if a server name is in
the allowlist.
agentjail policy
Manages individual policy rules.
agentjail policy list
Prints a table of all policy rules with their rule_id, status (on/off/locked), and source (Core/Optional/Custom).
agentjail policy list
Example output:
RULE STATUS SOURCE
file_policy/sensitive_credential locked Core
command_policy/no-sudo on Core
library/no_shell_init_write off Optional
custom/my_rule/no-something on Custom
- Core rules are always-on; most can be disabled with
--forceand interactive TTY confirmation (see below). - Locked rules (the self-protection set) can never be disabled by any means.
- Optional (library) rules are off by default; enable per your threat model.
- Custom rules are installed via
agentjail policy add.
agentjail policy enable / agentjail policy disable
Toggle library or core rules on or off. Changes are written to
~/.agentjail/policy.yaml as disabled_rules entries and the daemon
hot-reloads automatically. All mutations are logged to ~/.agentjail/audit.log.
agentjail policy enable no_shell_init_write
agentjail policy disable file_policy/sensitive_in_project
Disabling a core rule requires --force and an interactive terminal
(TTY) confirmation: an agent cannot disable a core rule non-interactively:
agentjail policy disable command_policy/no-sudo --force
# prompts: "This is a core rule. Confirm disable? [y/N]"
The locked self-protection set (file_policy/agentjail_self,
library/no-daemon-kill, library/no-hook-self-disable,
command_policy/no-policy-mutation, resolver/*) can never be disabled,
neither via policy.yaml edit nor CLI, regardless of --force.
agentjail policy add
Validates a custom Rego file and installs it, hot-reloading the daemon.
agentjail policy add ~/my_rule.rego
Before installing, agentjail policy add enforces:
package agentjailmust be declared.- No
decisiondeclaration: onlycandidate contains r if { ... }entries are allowed (resolver.regois the soledecisionproducer). custom/<stem>/<rule>namespace: every rule_id must start withcustom/<filename_stem>/(e.g.my_rule.rego→custom/my_rule/no-foo).- Full-bundle OPA compile: the file is compiled with the embedded core + library rules; a compile error rejects the file.
agentjail policy remove
Removes a custom rule by its file stem and hot-reloads the daemon.
agentjail policy remove my_rule
agentjail skill
Manages the skill allow/block/ask lists in ~/.agentjail/policy.yaml. Skills
are invoked as tool_name="Skill" with tool_input={"skill": "<name>"}.
Every mutation signals the daemon to reload policy.
agentjail skill list # show all known skills with policy status
agentjail skill list --json # machine-readable output
agentjail skill allow <skill> # add to skills.allowed
agentjail skill block <skill> # add to skills.blocked
agentjail skill ask <skill> # add to skills.ask
agentjail skill clear <skill> # remove from all lists
| Flag | Description |
|---|---|
--json | (list only) Output as JSON. |
--project <dir> | (allow/block/ask/clear) Write to <dir>/.agentjail/policy.yaml instead of the global config. |
Like agentjail policy, mutating the skill lists requires an interactive
terminal and a typed y confirmation - an agent cannot self-approve a skill.
agentjail trust / agentjail untrust
Manages the direnv-style trust list for per-project ./.agentjail/policy.yaml
overlays. A project overlay can only widen a session’s policy (add allowed
hosts or MCP servers); it can never drop the non-removable essentials, un-block
a blocked MCP, or clear disabled rules. Until a project is trusted, its overlay
is ignored. Trust is keyed on the file’s content hash, so editing the overlay
revokes trust until it’s re-approved.
agentjail trust # trust ./.agentjail/policy.yaml (searches up to the git root)
agentjail trust /path/to/repo # trust a specific project path
agentjail trust list # list trusted overlays and whether each still matches
agentjail untrust # remove the current project's overlay from the trust list
agentjail grants / agentjail grant
The human-facing side of runtime host grants (ADR 0047): a sandboxed session
can request egress to a new host with agentjail allow host <h>, and a human
outside the sandbox approves or denies the request here. These commands
authenticate against the daemon’s control socket with a token the sandboxed
agent cannot read, so they cannot be run by the agent itself.
agentjail grants # list pending grant requests
agentjail grants --log # show history of approved/denied grants
agentjail grant approve <grant_id> # approve a pending request
agentjail grant deny <grant_id> # deny a pending request
| Flag | Description |
|---|---|
--log | (grants only) Show the history of approved/denied grants from the local SQLite audit log instead of currently pending requests. |
Approving a grant persists the host into the owning session’s
.agentjail/policy.yaml overlay and re-trusts it, so future sessions inherit
the grant; the current sandboxed session picks it up on next launch.
agentjail credential
Stores provider-neutral credentials in AgentJail’s encrypted local broker and delivers them to selected shielded sessions. Each record has an arbitrary exact ID plus optional non-secret label and tags. AgentJail does not infer a provider, tool, account, environment, or permission level from any of those fields.
export SLACK_BOT_TOKEN="..."
agentjail credential set slack-channel-read-token \
--from-env SLACK_BOT_TOKEN \
--label "Release channel reader" \
--tag slack
agentjail credential set cluster-dev \
--from-file KUBECONFIG="$HOME/.kube/config"
agentjail credential list
agentjail credential remove cluster-dev
agentjail run --credential slack-channel-read-token -- codex
| Flag | Description |
|---|---|
--from-env <NAME> | Capture an environment variable and deliver it under the same name. Repeatable. |
--from-file <ENV=PATH> | Copy a file into a private mode-0600 session file and expose its path through ENV. Repeatable. |
--from-stdin <ENV> | Read one credential value from stdin and deliver it through ENV. |
--label <TEXT> | Add a non-secret description shown during agent discovery. |
--tag <TAG> | Add a non-secret discovery tag. Repeatable. |
Credential values are never accepted in argv. The CLI also rejects bindings that could replace executable search, dynamic loaders, proxy or TLS controls, shell startup, module paths, or SSH-agent state.
When the broker contains generic credentials, shielded Codex and Claude sessions
receive an MCP surface that lists non-secret IDs, labels, and tags, then requests
one exact ID. Every stored generic record is discoverable, including during a
session launched with --credential. Exact requests are auto-approved and
audited in v1.6.0.
Eager --credential delivery injects environment values before launch and
creates managed file bindings in a private mode-0700 session directory with
mode-0600 files. AgentJail removes that directory when the session ends.
An MCP request returns the real environment values or file contents to the agent. The agent applies those values or writes the file, so the material may remain in its transcript or in files it creates. AgentJail cannot guarantee cleanup of those copies.
Static material is available to the sandbox session, not confined to one executable inside it. The provider’s IAM or RBAC remains the real authority boundary, so scope each stored credential accordingly.
agentjail proxy
Runs one eligible host command from an authenticated shielded Codex session after Codex shows its native allow-once prompt. Linux and macOS share the same policy, proof, execution, output, timeout, audit, and failure contract.
agentjail proxy --reason "inspect open issues for this release" -- gh issue list --limit 10
--reason is required. It must be a non-empty, single-line UTF-8 explanation
of at most 512 bytes. Codex shows it in the native prompt so you can review why
the agent needs host access, not just what it wants to run.
Approval is bound to the reason, session, executable, exact argv, working directory,
project root, sanitized PATH, broker PID, and fresh process ancestry. Shells,
interpreters, sensitive clients, AgentJail control commands, and generic runtime
wrappers are denied. The command gets no stdin or TTY, has a 30-second timeout,
and can return at most 1 MiB across stdout and stderr.
The approved program runs as the user outside the shield. It can access normal host files, network, configuration, and keychains, so the native prompt is an authority boundary rather than a sandbox around the program.
agentjail secret
Manages credentials for the phantom-token registry: the agent never sees the real credential value, only a phantom token that the proxy swaps for the real value on outbound requests that match the access policy.
agentjail secret set github --from-env GITHUB_TOKEN --hosts api.github.com
agentjail secret set openai --value sk-... --hosts api.openai.com --header Authorization --scheme Bearer
agentjail secret list # show configured credentials (no values)
agentjail secret remove github
| Flag | Description |
|---|---|
--value <val> | Credential value (mutually exclusive with --from-env). |
--from-env <VAR> | Read the credential from the named environment variable. |
--hosts <hosts> | Required. Comma-separated allowed destination hosts. |
--methods <methods> | Comma-separated allowed HTTP methods (empty = all). |
--paths <globs> | Comma-separated allowed path globs (empty = all). |
--header <name> | HTTP header used for injection. Default Authorization. |
--scheme <scheme> | Auth scheme: Bearer, token, or empty. Default Bearer. |
--type <type> | Injection type: bearer_header, header, or query_parameter. Default bearer_header. |
--violation <action> | Enforcement action on a policy violation: block, block-and-log, or terminate. Default block-and-log. |
--ttl <duration> | Credential lifetime (e.g. 8h, 30m). |
set stores the value in the encrypted vault (via agentjail-secrets) and
writes the access policy to policy.yaml. remove deletes it from both.
agentjail update
Self-updates all agentjail binaries to the latest release from GitHub.
agentjail update # upgrade to the latest release
agentjail update --force # reinstall the current version (repair)
| Flag | Description |
|---|---|
--force | Reinstall even if already on the latest version (useful for repair). Downgrade is always refused, even with --force. |
Security gate: agentjail update requires an interactive terminal and a
typed y confirmation. If stdin is not a real TTY - or if the typed response
is anything other than y - the command refuses and exits. This prevents any
agent from triggering a self-update non-interactively.
Verification: before replacing any binary, the update command:
- Downloads the release tarball and its
SHA256SUMSmanifest throughreleases.agentjail.io(a Cloudflare proxy that provides integrity checks and analytics), falling back to GitHub Releases if the proxy is unreachable. - Verifies the SHA256 checksum of the tarball against the manifest.
- Verifies the minisign signature on
SHA256SUMS(when a signing key is embedded in the build; pre-release builds with no signed manifest skip this step).
Atomic swap + rollback: each binary is written to a temp file in the same
directory as the target, chmod 0755, then renamed over the live binary. If
any swap, role-symlink reconciliation, supervisor reload, restart, or versioned
health attestation fails, the exact prior files, symlinks, modes, and absences
are restored. The restored daemon is then restarted and attested. Successful
updates restart and attest the supervised daemon on both macOS and Linux, and
the terminal outcome is recorded through the authenticated control socket.
Binaries updated: the two real binaries, agentjail and agentjail-hook. The
role symlinks (agentjail-daemon, agentjail-shield, agentjail-secrets)
point at agentjail, so refreshing it updates them too.
agentjail feedback
Sends a one-off feedback message to the agentjail maintainers.
agentjail feedback "your message here"
agentjail feedback # interactive: prompts for message then contact
If no message is given as a positional argument, the command prompts for one interactively. After the message, it optionally prompts for a contact email address (press Enter to skip). The message is sent together with the installed agentjail version and OS, tied to the installation’s anonymous random ID.
If the build has no telemetry backend configured, the command prints a link to open a GitHub issue instead.
Testing a tool call manually (agentjail-hook)
Policy evaluation is performed by the agentjail-hook binary. To test a call
manually, pipe a Claude PreToolUse JSON payload to the hook with the daemon
already running:
echo '{"hook_event_name":"PreToolUse","tool_name":"Bash","tool_input":{"command":"rm -rf /"}}' \
| agentjail-hook
Output:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Blocked: rm -rf on absolute path"
}
}
Prefer agentjail try for quick checks: it requires no raw JSON.
Exit codes
| Code | Meaning |
|---|---|
0 | Call is allowed or requires confirmation (allow / ask). |
2 | Call is denied (deny). |
See also
- Configuration: config file, custom rules, and daemon flags.
- Default policies: what ships in the default bundle.