← All docs

CLI reference

The agentjail command-line interface: subcommands, flags, and example output.

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.

FlagDefaultDescription
--no-sandboxoffRun hook-only, without the OS sandbox.
--tunneloffRoute all traffic through the transparent tunnel (MITM + per-host policy, HTTP/2 + gRPC).
--require-tunneloffFail closed instead of falling back when the transparent tunnel is unavailable. AGENTJAIL_REQUIRE_TUNNEL=1 is the automation equivalent.
--credential <ID>noneDeliver the exact stored credential ID to the shielded session. Repeat to deliver more than one record.
--no-provider-gatewayoffDisable the base-URL LLM capture gateway.
--verboseoffMirror 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
FlagDescription
--for <agent>Wire a single agent: claude-code, codex, or cursor.
--allNon-interactive; wire every detected agent.
--allow-unsupportedDeprecated no-op. Linux is fully supported (systemd user service); kept only for old CI scripts.
--with-path-shimStandalone 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-apparmorStandalone 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
FlagDescription
--path-shim-onlyRemoves only the --with-path-shim binary and its shell-rc block. Leaves the hook, daemon, and ~/.agentjail untouched.
--keep-credentialsOn 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.
--forceA 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
FlagDescription
--action=<allow|ask|deny>Show only entries with this verdict.
--since=<duration>Limit to entries within the last duration (e.g. 1h, 30m).
-vAdds 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
FlagDefaultDescription
--period <duration>7dReport window, up to 90 days. Accepts values such as 24h, 7d, and 30d.
--project <path>all projectsFilter the displayed report to one project. Budget checks still use all collected sessions.
--jsonoffPrint the typed report and budget alerts as JSON.
--db <path>~/.agentjail/agentjail.dbRead 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
FlagDefaultDescription
--db <path>~/.agentjail/agentjail.dbPath to the SQLite event store.
--policy <path>~/.agentjail/policy.yamlPath to policy.yaml, used to frame the report (monitor mode vs. enforce mode).
--since <duration>24hTime range to report over (e.g. 1h, 7d, 30m); 0 for all time.
--jsonoffOutput 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.

FlagDefaultDescription
--db <path>~/.agentjail/agentjail.dbPath to the SQLite event store.
--since <duration>0Time range to report over, such as 24h, 7d, or 30m; 0 means all time.
--top <count>10Maximum rows shown in each ranked table.
--jsonoffOutput 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
FlagDefaultDescription
--db <path>~/.agentjail/agentjail.dbPath to the SQLite event store.
--activeoffShow only sessions with a live daemon connection.
--since <duration>24hOnly sessions active within this duration (e.g. 1h, 7d, 30m); 0 for all time.
--jsonoffOutput 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
FlagDescription
--session <id>Session ID to replay. Required unless --list is set.
--listList available sessions instead of replaying one.
--followFollow new decisions for the session as they arrive.
--verboseInclude redacted tool_input in the output.
--basicPlain-text output instead of the TUI.
--no-colorDisable 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 --force and 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:

  1. package agentjail must be declared.
  2. No decision declaration: only candidate contains r if { ... } entries are allowed (resolver.rego is the sole decision producer).
  3. custom/<stem>/<rule> namespace: every rule_id must start with custom/<filename_stem>/ (e.g. my_rule.rego → custom/my_rule/no-foo).
  4. 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
FlagDescription
--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
FlagDescription
--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
FlagDescription
--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
FlagDescription
--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)
FlagDescription
--forceReinstall 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:

  1. Downloads the release tarball and its SHA256SUMS manifest through releases.agentjail.io (a Cloudflare proxy that provides integrity checks and analytics), falling back to GitHub Releases if the proxy is unreachable.
  2. Verifies the SHA256 checksum of the tarball against the manifest.
  3. 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

CodeMeaning
0Call is allowed or requires confirmation (allow / ask).
2Call is denied (deny).

See also