← 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.1.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

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.

FlagDefaultDescription
--no-sandboxoffRun hook-only, without the OS sandbox.
--tunneloffRoute all traffic through the transparent tunnel (MITM + per-host policy, HTTP/2 + gRPC).
--no-provider-gatewayoffDisable the base-URL LLM capture gateway.

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.

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 a ~/.agentjail/bin/claude shadow binary plus an opt-in shell-rc block, so plain claude runs shielded. Can also be combined with --all/--yes to add the shim as part of a full install.
--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-secrets     # 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-secretsOn a full teardown, preserves secrets.key and the secrets/ directory (the credential vault) instead of wiping them with the rest of ~/.agentjail.
--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).

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 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) and a Network tab (captured LLM requests and responses, plus tunnel traffic).

agentjail ui

Policy status is read-only by default; pass --edit-policy only when you want enable/disable controls in the UI.

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 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.regocustom/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 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 rename fails, already-swapped binaries are restored from a pre-update backup. On macOS the daemon is stopped via launchd before the swap and restarted on success; on Linux, a note is printed to restart the daemon manually.

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