Skip to main content
Endor Labs hooks for Claude Code send a structured event for every session, user prompt, tool call, shell command, and file operation. The hook also enforces your Coding Agent Governance policies locally before each action reaches the agent.

Before you begin

Confirm the following requirements before you install the hook:
  • An admin has completed the prerequisites, including creating an API key with the AI Audit User role.
  • The target machine runs macOS, Linux, or Windows with Claude Code installed.
  • endorctl is on PATH. This applies to the hand-written configuration below. A generated configuration installs and updates endorctl automatically at session start.
Do not export ENDOR_TOKEN in the environment that launches Claude Code. Hooks authenticate with the API key and secret only, and on older versions of endorctl the extra token triggered a mixed-authentication error that blocked endorctl ai-audit.
Prefer generating this file over maintaining it by hand. The in-browser generator assembles settings.json (or a macOS configuration profile) from the mdm-scripts repository sources, and adds a bootstrap that installs and updates endorctl at session start.
Claude Code reads its credentials and namespace from the env block in settings.json, so the configuration is self-contained. Replace the placeholder values in env with your namespace and an API key issued for the AI Audit User role.

Install for one developer

Use this for a single-machine trial or a personal install.
  1. Open ~/.claude/settings.json in a text editor. Create the file if it does not exist.
  2. Paste the configuration shown in Before you begin under the hooks key. Merge with any existing hooks entries, because Claude Code does not deduplicate handlers across configurations.
  3. Save the file and restart any active Claude Code session.

Install on a managed fleet

Claude Code reads enterprise hooks from a managed settings file: /Library/Application Support/ClaudeCode/managed-settings.json on macOS, or /etc/claude-code/managed-settings.json on Linux. Use your MDM, such as Jamf, Intune, Kandji, or JumpCloud, to deliver that file to each managed machine. The env block in the configuration above carries the Endor Labs credentials, so you don’t need a separate shell setup.
On macOS, environment variables set in ~/.zshrc reach apps launched from a terminal but not apps launched from Spotlight. Ship the variables through your MDM payload (for example, a launchctl setenv profile or an ~/.zprofile snippet) for full coverage.
If your MDM’s deployment script rejects the inline JSON payload, encode the configuration in Base64 in the script, and decode it on the target machine. This avoids the quoting and escaping issues that some MDMs introduce when publishing JSON.

Per-repository overrides

Add <repository>/.claude/settings.json and commit it. Repository hooks layer on top of user and enterprise hooks and let security-sensitive projects extend the configuration. For developer-local additions outside source control, use <repository>/.claude/settings.local.json.

Claude Code hook events used by Coding Agent Governance

The table lists every event the hook processes. Claude Code events outside this set, such as Stop, PermissionRequest, and SubagentStart, are accepted and ignored if a configuration registers them, so an older configuration keeps working but those events record nothing. The PreToolUse hook fails open. If the hook itself errors out, Claude Code allows the tool call rather than blocking it and keeps working. The usual cause is a missing binary. An unreadable local policy cache does not disable enforcement, because the hook falls back to the built-in system policies. A successfully evaluated Block policy still stops the tool call.

Tune the hook

For an audit-only rollout, set ENDOR_AI_AUDIT_NO_BLOCKING=true in the hook environment. endorctl ai-audit then downgrades every Block action to Alert at evaluation time. For Cursor, set it in the shell that launches the IDE. For Claude Code, set it in the env block of settings.json. Policies still record violations under Policy Violations, but the hook never denies a . Use this to seed a new policy without interrupting developers, then unset the variable when you’re ready to enforce. Any value parsable as a Go bool (such as true, 1, or t) turns the option on. Unset, empty, or unparseable values keep enforcement on.

Verify hooks are firing

  1. Start a session in and ask the agent to run a benign shell command, such as ls.
  2. Select Agent Governance from the left sidebar, then select Workstation Inventory.
  3. Confirm the developer’s row shows a recent value under Last Active.
If no row appears, see Troubleshoot a quiet machine.

What developers see when a policy fires

When a policy with the Block action matches an event, the hook returns a deny response to . stops the and surfaces the User Message to the developer. The agent receives a deny response that carries the User Message, explains that a governance policy denied the action, and tells the agent not to work around the block. When a policy with the Ask Permission action matches, the hook returns an ask response. pauses and asks the developer to confirm or deny before the agent proceeds. When a policy with the Alert action matches, the hook allows the action to proceed. Endor Labs records the event under Policy Violations for your security team to review.

Troubleshoot a quiet machine

Run these checks if a developer’s actions never appear under Workstation Inventory or Policy Violations:
  • Confirm the developer has started at least one session. With the event cache enabled, the hook batches events and flushes them within about 30 seconds of hook activity, and fully at session start and end, so inventory Sessions, Last Active, and counts can lag the newest actions by that interval.
  • Hook errors fail open. If the hook cannot run or reach the Endor Labs API, allows the . The event is missing from inventory rather than surfacing an error. The remaining checks rule out the common causes.
  • Confirm endorctl is on PATH in the environment that runs the hook. The hook fails silently if the binary is not found. Run endorctl version from the same shell to verify.
  • Confirm only one endorctl installation is active. If endorctl ai-audit fails with Failed with non-blocking status code: No stderr output, conflicting installations are the likely cause, such as an npx-provisioned endorctl alongside a Homebrew install. Keep one installation method per machine, remove the others, then run endorctl version to confirm.
  • Confirm ENDOR_API, ENDOR_NAMESPACE, ENDOR_API_CREDENTIALS_KEY, and ENDOR_API_CREDENTIALS_SECRET are set for the process that runs the hook. Cursor reads them from the shell that launched it. Claude Code reads them from the env block in settings.json.
  • Confirm ENDOR_TOKEN is not also exported alongside your Coding Agent Governance API key credentials in the hook environment. Hooks rely only on ENDOR_API_CREDENTIALS_KEY and ENDOR_API_CREDENTIALS_SECRET. ENDOR_TOKEN is redundant and, on older versions of endorctl, triggered a mixed-authentication error that blocked endorctl ai-audit.
  • Confirm the API key has the AI Audit User role and has not expired.
  • Confirm the developer restarted after the hooks file changed. reads the configuration at session start.
  • Confirm the developer restarted after a policy edit. The local policy cache refreshes at session start.
  • Confirm the JSON file parses. A trailing comma silently disables every hook in the file.
  • Confirm the Endor Labs API is reachable from the environment that runs the hook. Network failures appear as gaps in the inventory.

Next steps

With hooks deployed, continue with the following pages: