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 / LinuxNative Windowsask behavior
Claude Code (claude-code)AvailableGit Bash onlyNative confirmation
Codex CLI (codex)AvailableUse WSL or a Linux containerDeny
GitHub Copilot CLI (copilot-cli)AvailableUse WSL or a Linux containerNative confirmation; deny in headless mode
Cursor (cursor)Available; real-agent validation pendingUse WSL / Remote-WSL or a Linux containerDeny
opencode (opencode)Available through a pluginUse WSL or a Linux containerDeny

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

ScopeUseAgents
localOne Claude Code project, outside shared project settingsClaude Code
projectShared project configuration; policy must be inside the projectAll five
user (default)Configuration for the current userAll five
managedMachine-wide configuration installed by an administratorAll 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: block installed by apply. Earlier versions can fail open; native fallback rules cover only literal rules that apply can 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; --pure and OPENCODE_PURE=1 skip 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.