agentjail works with zero configuration: install it, and the three core
rulesets (file_policy, command_policy, mcp_policy) are active
immediately. When you want to tune behaviour you have three levers: the
policy.yaml overlay file, user-supplied Rego rules, and daemon startup flags.
Config file: ~/.agentjail/policy.yaml
The primary configuration file is ~/.agentjail/policy.yaml (YAML). The
daemon reads it at startup and re-reads it on SIGHUP (which agentjail policy enable/disable/add/remove and agentjail mcp trigger automatically). The
decision cache is invalidated on every reload so changes take effect immediately.
The file is injected into OPA as data.agentjail.config, which Rego rules
read for allowlists, blocklists, and tuning values.
The top-level keys map to per-category tuning:
file:
extra_deny:
- ~/Projects/secrets
extra_allow:
- ~/Projects/generated-keys # path that would otherwise be blocked
commands:
extra_block:
- "curl.*internal.corp"
mcp:
allowed:
- filesystem
- github
blocked:
- "*stripe*"
- "*payment*"
servers:
filesystem:
allowed_tools: ["read_file", "list_directory"] # write_file implicitly denied
fetch:
allowed_tools: ["fetch"]
network:
allowed_hosts:
- api.openai.com
- api.anthropic.com
web:
blocked:
- "*.evil.com"
- "169.254.*" # block link-local metadata addresses
disabled_rules:
- file_policy/sensitive_in_project # suppress asking on in-project secrets
| Key | Purpose |
|---|---|
file.extra_deny | Additional path patterns to block on top of the built-in file policy. |
file.extra_allow | Path patterns to explicitly allow (takes effect before deny checks). |
commands.extra_block | Additional command patterns (regex) to deny on top of the built-in command policy. |
mcp.allowed | Allowlist of MCP server names the agent may call (glob patterns supported). |
mcp.blocked | Blocklist of MCP server names; always wins over mcp.allowed. |
mcp.servers.<name>.allowed_tools | Per-server tool allowlist. When non-empty, only the listed tool names may be called on that server; all others are denied with mcp_policy/tool_not_allowed. When absent or empty, all tools of an allowed server are permitted (backwards-compatible default). |
network.allowed_hosts | Allowlist of hostnames the agent may reach. |
web.blocked | Array of host glob patterns; a WebFetch whose URL host matches any pattern is denied (web_policy/fetch_blocked). WebSearch is unaffected. Patterns match case-insensitively and * spans dots. Empty by default. |
disabled_rules | List of rule_id values (or policy/* globs) to suppress. The locked self-protection set can never be suppressed here. |
Sample configurations suitable for different environments are provided in the
repository at samples/configs/:
policy-strict.yaml: zero-trust defaultpolicy-mcp-heavy.yaml: per-tool allowlists for filesystem/fetch/githubpolicy-dev-permissive.yaml: relaxed for trusted local dev
Daemon startup flags
| Flag | Description |
|---|---|
--policy <path> | Path to a policy.yaml overlay (defaults to ~/.agentjail/policy.yaml). |
--rules <dir> | Directory of *.rego files to load in addition to the embedded core rules (non-recursive). |
Environment variables
| Variable | Effect |
|---|---|
AGENTJAIL_AUTO_UPDATE | Controls whether the daemon auto-applies updates it finds. Defaults to enabled; set to false to stop the daemon from applying updates on its own. |
AGENTJAIL_NO_UPDATE_CHECK | Disables the CLI’s background update check entirely - no throttled version check, no stderr notice, no update telemetry. |
Adding custom Rego rules
The recommended way to add a custom rule is via the CLI: it validates the authoring contract and hot-reloads the daemon automatically:
# Install + validate in one step (recommended)
agentjail policy add ~/my_rule.rego
# Remove a custom rule by file stem
agentjail policy remove my_rule
# See all rules including custom ones
agentjail policy list
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.
Manual install (no validation)
You can also drop a .rego directly into ~/.agentjail/rules/ and SIGHUP the
daemon, but this skips authoring-contract validation:
cp my-org-policy.rego ~/.agentjail/rules/my-org-policy.rego
kill -HUP $(pgrep agentjail-daemon)
Bad custom rules are quarantined
If a custom rule file in ~/.agentjail/rules/ breaks the OPA bundle at daemon
startup (for example after a manual edit), the daemon skips it with a WARN
log rather than failing to start. The baseline (core + valid library rules)
always loads. Fix the file and SIGHUP to reload.
Which rules can be disabled
Core rules (file_policy, command_policy, mcp_policy) can be disabled
via agentjail policy disable <rule_id> --force with an interactive TTY
confirmation. This is intentionally gated to prevent an agent from turning off
core protections non-interactively.
Library rules can be toggled without --force:
agentjail policy enable no_shell_init_write
agentjail policy disable no_shell_init_write
The locked self-protection set can never be disabled by any means:
file_policy/agentjail_selflibrary/no-daemon-killlibrary/no-hook-self-disablecommand_policy/no-policy-mutationresolver/*
All mutations are logged to ~/.agentjail/audit.log.
Viewing active configuration
agentjail policy list shows every rule, its status, and its source:
agentjail policy list
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
Library rules show source Optional. Core rules show source Core. Custom
rules (installed via agentjail policy add) show source Custom.
See also
- Default policies: what the core rulesets block.
- CLI reference:
policy list,policy enable/disable/add/remove,mcp, and daemon flags.