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 are supported and under active testing. The Cursor editor is supported, with real-agent validation pending. 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; CLI validated with a real agent, editor 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, or
$CODEX_HOME/hooks.json when CODEX_HOME is set.
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.
Codex does not hook write_stdin, which types into a running command, so a command that
asks for a terminal (tty) is denied; without one, a command gets no input.
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.
Install only hooks you trust: Cursor runs every matching hook, a later preToolUse hook
can replace a tool’s input after CyberBoar checked it, and a sessionStart hook can set
environment variables for every later hook.
The agent’s shell keeps its directory, variables and aliases between calls. When the
agent leaves the Shell tool’s working directory empty, the Cursor CLI does not tell the
hook which directory the shell is in, so a command with a relative path is denied unless
it starts with cd to an absolute directory (cd /absolute/path/to/project && go test ./...); the denial tells the agent so. A call that sets the working directory is checked
in it. Paths under ~ are always unknown, since an earlier call may have changed HOME.
Restart/reload Cursor, inspect its hook diagnostics, and test the real agent before relying on this integration. The Cursor CLI has passed the real-agent harness; the Cursor editor has not been validated yet.
opencode
Official reference: opencode plugins and hook events.
opencode uses a JavaScript plugin, not hooks.json. It loads project plugins from
.opencode/plugin/ or .opencode/plugins/, and user plugins from the same directories
under ~/.config/opencode/ (or XDG_CONFIG_HOME). CyberBoar uses the singular
plugin/, so apply replaces a manual copy instead of adding a second one. Keep one
copy only.
From a verified CyberBoar source checkout matching your binary, copy the complete
tested project plugin
to a new .opencode/plugin/cyberboar.js in your project. For example, from the
checkout root:
mkdir -p /absolute/path/to/project/.opencode/plugin
cp -i internal/adapters/opencode/testdata/apply/project-plugin.js /absolute/path/to/project/.opencode/plugin/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. Cursor CLI passed the real-agent harness; Cursor editor sessions remain unverified. - 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.