Agent setup
Choose automatic installation with cyberboar apply, or configure the hooks
manually. Both run the same cyberboar hook policy engine;
apply is a configuration helper, not a prerequisite for enforcement. Preview its
settings first; add --write to install them. Keep the binary at its installed path and
back up settings. For a complete first installation, follow Getting
started.
For a short allowed/denied test with each integration, follow the 60-second agent demos. The official Claude Code, Codex and opencode editor extensions and the Cursor editor are supported and under active testing. Copilot editor support is experimental; this does not change the Copilot CLI setup below. See Editor integrations for setup and current validation limits.
Choose an integration
Agent (--agent) | macOS / Linux | Native Windows | ask behavior |
|---|---|---|---|
Claude Code (claude-code) | Available | Git Bash only | Native confirmation |
Codex CLI (codex) | Available | Use WSL or a Linux container | Deny |
GitHub Copilot CLI (copilot-cli) | Available | Use WSL or a Linux container | Native confirmation; deny in headless mode |
Cursor (cursor) | Available; real-agent validation pending | Use WSL / Remote-WSL or a Linux container | Deny |
opencode (opencode) | Available through a plugin | Use WSL or a Linux container | Deny |
Use the Linux binary inside WSL or a Linux container. A human can use PowerShell to install CyberBoar on Windows; this does not mean the engine analyzes PowerShell tool calls. See PowerShell status.
Select a scope
| Scope | Use | Agents |
|---|---|---|
local | One Claude Code project, outside shared project settings | Claude Code |
project | Shared project configuration; policy must be inside the project | All five |
user (default) | Configuration for the current user | All five |
managed | Machine-wide configuration installed by an administrator | All except opencode |
At user, local and managed scope, apply records the executable’s own path. Project
scope uses cyberboar on PATH unless --command specifies a path. Each developer
using shared settings needs the binary available there. --dir selects the project for
local/project scope.
Preview and install
Run from a project with a validated .cyberboar/policy.yaml. These are previews:
cyberboar apply --agent claude-code --scope local --policy .cyberboar/policy.yaml
cyberboar apply --agent codex --scope project --policy .cyberboar/policy.yaml
cyberboar apply --agent copilot-cli --scope project --policy .cyberboar/policy.yaml
cyberboar apply --agent cursor --scope project --policy .cyberboar/policy.yaml
cyberboar apply --agent opencode --scope project --policy .cyberboar/policy.yaml
Choose the agent you use, inspect the target files and warnings, then repeat its command
with --write. For decision logging, include --audit in both commands. The .bak
produced by apply can be replaced on later runs, so retain an independent pre-install
backup.
Reload or restart the agent. Codex user/project hooks must also be trusted in /hooks
before enforcement starts. Test a policy-denied call and confirm its audit event when
logging is enabled. An agent refusing a request on its own does not prove the hook ran.
Manual hook configuration
The examples below are project-level configurations for macOS/Linux, or for the Linux
binary inside WSL/a Linux container. Start with a validated .cyberboar/policy.yaml in
the project root and cyberboar on the agent’s PATH. Native Windows users should use
Claude Code with Git Bash and an executable path to cyberboar.exe instead.
Back up existing files. Merge these handlers into existing hook arrays; do not replace unrelated hooks or settings. Use only one CyberBoar installation per scope to avoid duplicate checks and audit events. The examples include an optional session briefing: remove only its session-start handler if you do not want the advice. Never make the pre-tool check asynchronous or ignore its exit status.
For a user-level installation, use the user configuration location listed below and
absolute binary/policy paths instead of the project-relative paths. To require signed
policies, add --pubkey /absolute/path/policy-signing.pub to both hook and brief.
For logging/tripwire state, add --audit /absolute/path/audit.jsonl and
--state /absolute/path/hook-state to hook only. The parent directories must be
accessible to the account running the agent. Do not let project environment variables
choose these protected paths. See the CLI reference.
Manual hook configuration does not reproduce all of apply’s native permission
fallbacks or managed locking. Protect configuration ownership separately; use the
managed deployment guide for administrator-enforced installations.
Claude Code
Official reference: Claude Code hooks.
Merge into .claude/settings.json (shared project), or
.claude/settings.local.json (local project). User configuration is
~/.claude/settings.json. The exec-form args avoid shell quoting, and Claude Code
substitutes ${CLAUDE_PROJECT_DIR} in each argument. Use Claude Code 2.1.295 or
later for onFailure: block; older versions can run tools when the hook fails.
{
"hooks": {
"PreToolUse": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "cyberboar",
"args": ["hook", "--policy", "${CLAUDE_PROJECT_DIR}/.cyberboar/policy.yaml", "--deadline", "5s"],
"timeout": 10,
"onFailure": "block"
}
]
}
],
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "cyberboar",
"args": ["brief", "--policy", "${CLAUDE_PROJECT_DIR}/.cyberboar/policy.yaml"],
"timeout": 10
}
]
}
]
},
"permissions": {
"deny": ["PowerShell"]
}
}
Keep PowerShell denied: the engine does not analyze that tool. Ensure no active
settings set disableAllHooks. Review the handlers in /hooks, restart/reload Claude
Code as required, and test enforcement in a new session.
Codex CLI
Official reference: Codex hooks.
Merge into .codex/hooks.json; user configuration is ~/.codex/hooks.json.
This example assumes Codex starts from the project root. Hook commands run from the
session’s working directory, so .cyberboar/policy.yaml is relative to that directory.
If you start Codex from a subdirectory, use an absolute policy path or the Git-root
alternative below.
{
"hooks": {
"PreToolUse": [
{
"hooks": [
{
"type": "command",
"command": "cyberboar hook --agent codex --policy .cyberboar/policy.yaml --deadline 5s",
"timeout": 10
}
]
}
],
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "cyberboar brief --agent codex --policy .cyberboar/policy.yaml",
"timeout": 10
}
]
}
]
}
}
No matcher means all tool calls are checked. Trust the project and review/trust the
handlers in /hooks after creating or changing them. Until trusted, Codex skips
non-managed hooks. ask decisions deny; a hook that cannot launch can fail open.
Optional Git-root path: OpenAI recommends Git-root resolution for repo-local
hooks that must work when Codex starts from a subdirectory. In both commands above,
replace .cyberboar/policy.yaml with
\"$(git rev-parse --show-toplevel)/.cyberboar/policy.yaml\" inside the JSON string.
This requires Git and a Git worktree; the escaped quotes preserve paths with spaces.
See the official hook configuration notes.
GitHub Copilot CLI
Official reference: GitHub Copilot hooks reference.
Create .github/hooks/cyberboar.json; user configuration is
~/.copilot/hooks/cyberboar.json (or under COPILOT_HOME). The CLI’s exec form runs
CyberBoar directly without a shell. Repository hooks run from the repository root.
{
"version": 1,
"hooks": {
"preToolUse": [
{
"type": "command",
"exec": "cyberboar",
"args": ["hook", "--agent", "copilot-cli", "--policy", ".cyberboar/policy.yaml", "--deadline", "5s"],
"timeoutSec": 15
}
],
"sessionStart": [
{
"type": "command",
"exec": "cyberboar",
"args": ["brief", "--agent", "copilot-cli", "--policy", ".cyberboar/policy.yaml"],
"timeoutSec": 15
}
]
}
}
This is for Copilot CLI, not the VS Code extension or cloud agent. Ensure the
scope’s settings do not set disableAllHooks. Reload Copilot and test a denied call.
Keep the 5-second decision deadline below the 15-second timeout: timeouts can fail open.
Cursor
Official reference: Cursor hooks.
Merge into .cursor/hooks.json; user configuration is ~/.cursor/hooks.json.
Project hooks run from the project root. Keep all five pre-tool handlers: the general
handler does not replace the separate file-read, tab-read, shell and MCP checks.
{
"version": 1,
"hooks": {
"preToolUse": [
{"command": "cyberboar hook --agent cursor --policy .cyberboar/policy.yaml --deadline 5s", "timeout": 15, "failClosed": true}
],
"beforeShellExecution": [
{"command": "cyberboar hook --agent cursor --policy .cyberboar/policy.yaml --deadline 5s", "timeout": 15, "failClosed": true}
],
"beforeMCPExecution": [
{"command": "cyberboar hook --agent cursor --policy .cyberboar/policy.yaml --deadline 5s", "timeout": 15, "failClosed": true}
],
"beforeReadFile": [
{"command": "cyberboar hook --agent cursor --policy .cyberboar/policy.yaml --deadline 5s", "timeout": 15, "failClosed": true}
],
"beforeTabFileRead": [
{"command": "cyberboar hook --agent cursor --policy .cyberboar/policy.yaml --deadline 5s", "timeout": 15, "failClosed": true}
],
"sessionStart": [
{"command": "cyberboar brief --agent cursor --policy .cyberboar/policy.yaml", "timeout": 15}
]
}
}
failClosed blocks execution failures/timeouts. CyberBoar maps ask to denial.
Restart/reload Cursor, inspect its hook diagnostics, and test the real agent before
relying on this integration; real-agent validation is still
pending.
opencode
Official reference: opencode plugins and hook events.
opencode uses a JavaScript plugin, not hooks.json. Local plugins are loaded from
.opencode/plugins/; user plugins use ~/.config/opencode/plugins/ (or
XDG_CONFIG_HOME). CyberBoar’s installer uses the compatible singular plugin/
location. Use one location only, not duplicate copies in both directories.
From a verified CyberBoar source checkout matching your binary, copy the complete
tested project plugin
to a new .opencode/plugins/cyberboar.js in your project. For example, from the
checkout root:
mkdir -p /absolute/path/to/project/.opencode/plugins
cp -i internal/adapters/opencode/testdata/apply/project-plugin.js /absolute/path/to/project/.opencode/plugins/cyberboar.js
Leave its implementation intact. Configure the constants at the top of your copy:
const name = "cyberboar";
const command = "cyberboar";
const hookArgs = ["hook", "--agent", "opencode", "--policy", ".cyberboar/policy.yaml", "--deadline", "5s"];
const briefArgs = ["brief", "--agent", "opencode", "--policy", ".cyberboar/policy.yaml"];
const timeoutMs = 15000;
Keep the existing project-root cwd expression. For a user plugin, use absolute
binary/policy paths and set const cwd = undefined; instead. Set briefArgs = null if
you do not want the optional briefing. Add signing/logging/state arguments to these
arrays as described above; they are passed directly, not through a shell.
The complete shim preserves config-derived shell/MCP context, per-call working
directory, the 15-second process timeout, output-size limits and strict response
validation. It throws to block a call unless the hook exits 0 with exactly
{"decision":"none"}. A shortened shell wrapper that checks only the exit status is
not equivalent. It also wires the optional briefing into the system prompt.
Restart opencode after editing. Do not use --pure or OPENCODE_PURE=1, which skip
plugins; a plugin load failure also leaves calls unchecked. Check startup diagnostics
and test a denied call. Install only trusted plugins: another plugin can change a call
after CyberBoar checked it.
Verify a manual installation
In a throwaway project, create .env.cyberboar-demo containing dummy data and deny
**/.env* in the policy. Ask the agent to read it, then to run a harmless permitted
command. Confirm the CyberBoar rule/reason for the denial and, if --audit is configured,
both decision events. For shell/JSON hook diagnostics and recovery, see
Troubleshooting. cyberboar explain alone does not prove the
agent loaded a manual hook.
Failure behavior
CyberBoar denies invalid input and decision errors. The agent determines what happens when its hook never runs:
- Claude Code 2.1.295 and later honors
onFailure: blockinstalled byapply. Earlier versions can fail open; native fallback rules cover only literal rules thatapplycan translate. - Codex can fail open when the hook cannot launch. Managed prefix rules provide a limited fallback for literal command rules.
- Copilot CLI can fail open on timeout or invalid JSON; other failures deny.
- Cursor hooks are installed with
failClosed, but the adapter has not been validated in a real Cursor session. - The opencode plugin denies execution failures. A plugin that fails to load is
skipped;
--pureandOPENCODE_PURE=1skip plugins entirely.
The capability matrix lists verified versions, tool coverage, missing working-directory information and hook visibility.
Managed enforcement
User/project installations are advisory to a user who can change them. Managed deployments need OS ownership and permissions protecting the binary, signing key, policy and agent configuration.
--lock requires managed scope and supports only Claude Code and Codex. Copilot uses
its root-owned policy directory. Cursor supports machine-wide hooks, but apply cannot
configure dashboard-managed team hooks. opencode has no managed scope in CyberBoar. See
MDM deployment.
Updates and removal
Re-run apply with the original scope/options to change hook commands. Keep older
binaries while sessions still reference them. Restore or carefully edit settings before
deleting a binary. There is no uninstall subcommand; the local removal
procedure illustrates how to
preserve unrelated configuration.