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 with the Cortex Code CLI (
cortex) installed. Endor Labs hasn’t verified Cortex Code on Linux or native Windows yet. - endorctl is on
PATH. - The environment that launches Cortex Code has these environment variables set:
ENDOR_API(for example,https://api.endorlabs.com)ENDOR_NAMESPACEENDOR_API_CREDENTIALS_KEYENDOR_API_CREDENTIALS_SECRET
endorctl ai-audit cortexcode with no flags, so endorctl reads the credentials from the environment. Use the following hook configuration.
ENDOR_AI_AUDIT_CACHE_ENABLED. The hook queues events locally and sends them on its next run after 30 seconds, at SessionEnd, and at the next SessionStart. The configuration registers no Stop hook, so events from the end of a session can arrive late, but they are not lost.
The timeout value is the longest Cortex Code waits for each hook. endorctl sets its own shorter time limit, 5 seconds by default. If the hook runs out of time, Cortex Code allows the tool call.
Install for one developer
Use this for a single-machine trial or a personal install.- Open
~/.snowflake/cortex/hooks.jsonin a text editor. Create the file if it does not exist. - Paste the configuration shown in Before you begin. If the file already has hooks, add the Endor Labs entries under its existing
hookskey. - Save the file and start a new Cortex Code session.
$CORTEX_HOME if set, else $SNOWFLAKE_HOME/cortex, else ~/.snowflake/cortex. Put hooks.json in the first folder that applies. See Known limitations for how a custom home affects inventory.
Install for a repository
Add the Endor Labs entries from the configuration under thehooks key of <repository>/.cortex/settings.json, and commit the file. Every developer who runs Cortex Code in that repository then runs the hook.
Install on a managed fleet
Cortex Code has no managed hooks path, so an administrator can’t lock the hooks in place. A developer can edit or remove both the user file and the repository file. You can’t guarantee coverage on every machine, so combine the following:- Use your MDM, such as Jamf, Intune, Kandji, or JumpCloud, to deliver
~/.snowflake/cortex/hooks.jsonand the four environment variables to each developer. - Commit
.cortex/settings.jsonwith the hooks to the repositories your developers work in.
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.Configuration the hook reads at session start
AtSessionStart, the hook takes a snapshot of the Cortex Code configuration for inventory and session policies. It reads the snapshot once per session and doesn’t rescan during the session.
- User level:
settings.json,hooks.json,mcp.json, andpermissions.jsonunder$SNOWFLAKE_HOME/cortex(default~/.snowflake/cortex). The hook also reads hooks from~/.claude/settings.jsonand MCP servers from~/.claude.json. - Project level:
.cortex/settings.json,.cortex/settings.local.json,.claude/settings.json, and.claude/settings.local.json. The.claudefiles contribute hooks only. The project directory isCORTEX_PROJECT_DIRwhen set, otherwise the hook’s working directory, not the Git root. - MCP servers: The hook merges servers by name, and the last source wins. The order is the top level of
~/.claude.json, then its entry for the project directory, then$SNOWFLAKE_HOME/cortex/mcp.json. - Enterprise MCP servers: Servers from the managed
files.mcpFilesetting stay separate from the merged list. The setting must be an absolute path.
~/.claude.json only when importClaudeMcpServers is on, which is the default. A project-level importClaudeMcpServers value overrides the user-level one.
Managed settings and MDM policy
Cortex Code accepts a managed settings file and an MDM policy from your administrator. Neither one delivers hooks, but the hook reads both atSessionStart to report sandbox posture, permission bypass, and enterprise MCP servers.
Managed settings file
The hook reads the managed settings file from a fixed path on each platform. The hook ignores the whole file and reports the sandbox posture as Unknown when the file fails its trust check or any of the following validations:versionis exactly"1.0".permissions.defaultModeisallowordeny.sql.defaultModeisread-onlyorwrite.sql.lockModeappears only together withsql.defaultMode.settings.forceSandboxModeisregularorautoAllow.defaults.themeisdark,light, orpro.required.minimumVersionis a semantic version without avprefix.
MDM policy
On macOS and Windows, the hook also reads a Cortex Code MDM policy. The policy holds the managed settings JSON as a Base64-encoded value.- macOS: Preference domain
com.snowflake.coco. The hook reads/Library/Managed Preferences/<username>/com.snowflake.coco.plist, then/Library/Managed Preferences/com.snowflake.coco.plist. For each key, the first file that sets it wins. - Windows: Registry key
HKLM\SOFTWARE\Policies\Microsoft\CortexCode.
settings.forceSandboxEnabled, the whole permissions block, and files.mcpFile. Every other setting comes from the file.
Any of the following MDM policy failures reports the sandbox posture as Unknown:
- The value is unreadable or larger than 256 KiB.
- The value isn’t valid Base64, isn’t valid JSON, or fails schema validation.
- The property list is larger than 1 MiB, or
plutiltimes out.
Sandbox posture
The hook resolves each session’s sandbox posture in the following order, and the first rule that applies wins:- A trusted managed
settings.forceSandboxEnabled: truereports Sandboxed. - Any warning while reading the configuration, such as an ignored managed file or a failed MDM policy, reports Unknown.
- The first explicit
sandbox.enabledvalue in the project.cortex/settings.json, then in$SNOWFLAKE_HOME/cortex/settings.json, sets the posture. - Otherwise, the posture is Not sandboxed.
forceSandboxEnabled: false doesn’t force the sandbox off. On Windows, forceSandboxEnabled: true in the managed settings file alone reports Unknown, never Sandboxed, because the hook can’t trust the file. An MDM policy that forces the sandbox reports Sandboxed.
See Sandbox posture to read the posture in inventory, and Session sandbox policies to act on it.
Permission bypass
The hook reports permission bypass (dangerouslyAllowAll) from the managed level only. When managed settings are present, the hook reports bypass as disabled unless they set dangerouslyAllowAll: true. A user-level dangerouslyAllowAll value never reports, and the Windows managed settings file alone never reports bypass state.
Cortex Code hook events used by Coding Agent Governance
The following table lists every event the hook processes. The hook accepts and ignoresStop, Notification, PermissionRequest, and SubagentStop if a configuration registers them. Those events record nothing.
How Cortex Code tools map to policies
The hook maps each Cortex Code tool to a policy template by tool name. No policy template inspects the SQL thatsql_execute runs. Cortex Code names its sub-agent tool Task, so policies written for the Claude Code Agent tool don’t match it.
Enforcement behavior
If the hook can’t run or doesn’t finish in time, Cortex Code allows the tool call and keeps working, so a hook problem never blocks a developer. The usual cause of a hook that can’t run is a missing binary. endorctl gives each hook run a time limit of 5 seconds by default, or 10 seconds when your policies use the AI judge.ENDOR_AI_AUDIT_HOOK_TIMEOUT overrides the limit.
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.
On a policy match at PreToolUse, a Block policy denies the tool call, and Cortex Code shows the reason from the policy. An Ask Permission policy shows Cortex Code’s own permission prompt, without the reason from the policy. An Alert policy lets the call proceed and shows the developer nothing, so only Endor Labs records the match.
User attribution
The hook attributes Cortex Code events to the value ofENDOR_ACTOR when the hook environment sets it. Otherwise, it uses the operating system login.
Tune the hook
For an audit-only rollout, setENDOR_AI_AUDIT_NO_BLOCKING=true in the Snowflake Cortex Code 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 tool call. Use audit-only mode to seed a new policy without interrupting developers, then unset the variable when you’re ready to enforce.
Any value that Go parses as a bool (such as true, 1, or t) turns the option on. Unset, empty, or unparseable values keep enforcement on.
Verify hooks are firing
- Start a session in Snowflake Cortex Code and ask the agent to run a benign shell command, such as
ls. - Select Agent Governance from the left sidebar, then select Inventory. The page opens on the Workstation Inventory tab.
- Confirm the developer’s Snowflake Cortex Code row shows a recent value under Last Active.
What developers see when a policy fires
When a policy with the Block action matches an event, the hook returns a deny response to Snowflake Cortex Code. Snowflake Cortex Code stops the tool call and shows the User Message to the developer when the hook response can carry it. A response that includes a message also 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, Snowflake Cortex Code asks the developer to confirm or deny, where it can pause at that event. Where it cannot, the outcome depends on the event. Endor Labs records the match under Policy Violations as Ask either way. See Enforcement behavior to review the per-agent behavior. 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 missing events
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 sends them to Endor Labs within about 30 seconds of hook activity. The hook also sends every queued event at session start and end. Inventory Sessions, Last Active, and counts can therefore lag the newest actions by that interval.
- Hook errors never block the developer. If the hook cannot run or reach the Endor Labs API, Snowflake Cortex Code allows the tool call. The event is missing from inventory, and no error appears. The remaining checks rule out the common causes.
- Confirm endorctl is on
PATHin the environment that runs the hook. If the binary is not found, the hook does nothing and shows no error. Runendorctl versionfrom the same shell to verify. - Confirm only one endorctl installation is active. If
endorctl ai-auditfails withFailed with non-blocking status code: No stderr output, conflicting installations are the likely cause, such as annpx-provisioned endorctl alongside a Homebrew install. Keep one installation method per machine, remove the others, then runendorctl versionto confirm. - Confirm
ENDOR_API,ENDOR_NAMESPACE,ENDOR_API_CREDENTIALS_KEY, andENDOR_API_CREDENTIALS_SECRETare set for the process that runs the hook. Cursor reads them from the shell that launched it. Claude Code reads them from theenvblock insettings.json. - Confirm
ENDOR_TOKENis not also exported alongside your Coding Agent Governance API key credentials in the hook environment. Hooks rely only onENDOR_API_CREDENTIALS_KEYandENDOR_API_CREDENTIALS_SECRET.ENDOR_TOKENis redundant and, on older versions of endorctl, triggered a mixed-authentication error that blockedendorctl ai-audit. - Confirm the API key has the AI Audit User role and has not expired.
- Confirm the developer restarted Snowflake Cortex Code after the hooks file changed. Snowflake Cortex Code reads the configuration at session start.
- Confirm the developer restarted Snowflake Cortex Code 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.
Known limitations
Cortex Code support has the following limitations:- Session policies: A Block or Ask Permission session policy doesn’t stop a Cortex Code session, because Cortex Code ignores
continue: falseatSessionStart. A match on a Cortex Code session only records the violation. - Claude Code hooks in Cortex Code sessions: Cortex Code also runs hooks from
~/.claude/settings.json,.claude/settings.json, and.claude/settings.local.json. Events from anendorctl ai-audit claudecodehook there record as Claude Code, so one Cortex Code session can appear under both agents. - Custom home directory: The hook reads configuration under
SNOWFLAKE_HOMEbut ignoresCORTEX_HOME, and AI tool discovery looks only in~/.snowflake/cortex. - Two inventory rows on one device: A device can show both a governed Snowflake Cortex Code agent and a discovered
cortex-code-cliAI tool. - Skills: Endor Labs doesn’t collect Cortex Code skills, so they don’t appear on the Skills tab.
- Project MCP servers and permissions: The hook doesn’t read MCP servers or permissions declared at the project level. Those servers can appear in inventory from their tool calls, without an Endor Score.
- Windows managed settings file: The hook doesn’t check the file’s access control list, so the file alone can’t make the posture Sandboxed. Use the MDM policy to force the sandbox on Windows.
- Headless runs: Endor Labs hasn’t verified the hook with headless
cortex -pandcortex execruns.
Next steps
With hooks deployed, continue with the following pages:- See Triage policy violations to set your daily review workflow.
- See Read the Coding Agent Governance overview to track adoption and enforcement trends.