Enterprise

Enterprise threat model

Who DefenseClaw trusts, where each trust boundary sits on Windows, Linux and macOS, what a standard user can and cannot do, and which risks remain in the standalone enterprise profile.

An enterprise deployment exists to stop two things: a standard user turning DefenseClaw off, and an AI agent working around it. This page explains how that holds on Windows, Linux and macOS, and where it stops. It covers the standalone profile, which an MDM, a package or an administrator installs. The Secure Client profile is described in Enterprise hardening and deployment.

The full threat models, with one row per threat and the code and tests behind each control, are in the repository. They are listed at the end of this page.

Terms used on this page

TermMeaning
GatewayThe service that inspects each agent event and answers allow or deny.
Hookdefenseclaw-hook, the small program the agent runs for each event, such as a tool call. It forwards the event to the gateway.
GuardianThe service that installs and repairs DefenseClaw's hook registration in each enrolled user's agent config.
EnumeratorThe service that finds the users and agents to protect and writes the target manifest.
Authorization ledgerThe administrator-owned record of which user is protected for which agent. The gateway reads it to decide who may use a hook.
Machine policyThe agent vendor's machine-wide settings, such as Codex requirements.toml. A standard user cannot edit them.
Per-user connectorAn agent with no machine policy, so DefenseClaw registers its hook in the user's own config and the guardian keeps it there.

Each term is defined in more detail in Concepts.

Who is trusted

Trusted:

  • administrators, root, SYSTEM and LocalSystem;
  • your MDM and the agent it runs on each computer;
  • the publisher that signs the release, or the SHA-256 manifest you pin.

Not trusted:

  • a standard user;
  • any AI agent that user runs, and anything a prompt can steer it to do;
  • other local users;
  • the gateway process, if it is compromised.

DefenseClaw does not defend a computer from its own administrator. An agent that runs with unrestricted sudo or an elevated administrator session is an administrator. A developer who can become an administrator (a member of the local Administrators group on Windows, even with a filtered UAC token; the admin group on macOS; sudo or wheel rights on Linux) can remove DefenseClaw by elevating, so the controls on this page hold for standard accounts. Keep agents, and the developers who run them, on standard accounts.

Trust zones

DefenseClaw places every component in one of six zones. The zone decides what the component may touch.

ZoneHoldsTrust
Z0 · Admin and MDMThe MDM agent, the package installer and the lifecycle commandsTrusted
Z1 · ServicesThe guardian, the enumerator and the sensor helperPrivileged; trusted
Z2 · GatewayThe gateway, under its own low-privilege accountRestricted; it cannot change policy
Z3 · Admin-owned filesBinaries, config, policies, secrets, the target manifest, the authorization ledger and vendor machine policyWritten only by administrators and DefenseClaw's privileged services
Z4 · User sessionThe AI agent, the hook as it runs for the user, and the user's own filesUntrusted
Z5 · CloudCisco AI Defense, used only when an administrator stores an API keyExternal

In each diagram, an arrow that crosses a zone border is a trust boundary. Its label names the channel. The controls on each boundary are in How each boundary is protected.

Windows

SCM · protected ACLs
owned entries
Codex policy
writes as the user
loaded by
runs
TCP · PID check
local socket
read-only
HTTPS · optional
TrustedZ0 · Admin and MDM (SYSTEM)
PrivilegedZ1 · Services (LocalSystem)
ProtectedZ3 · Admin-owned files
UntrustedZ4 · User session (untrusted)
RestrictedZ2 · Gateway (virtual account)
ExternalZ5 · Cloud (external)
OperatorMDM or adminSetup · lifecycle
SystemHook guardianhook enumerator
SystemSensor helper
PolicyConfig · secretsmanifest · ledger
PolicyVendor machinepolicy
Agent runtimeAI agentuser config · hooks
Connectordefenseclaw-hook.exe
Control planedefenseclaw-gateway
SystemCisco AI Defense
Windows. An arrow that crosses a zone border is a trust boundary; its label names the channel.
ZoneWhat runs or lives thereIdentity
Z0The MDM agent or an administrator, running Setup (DefenseClawSetup-Enterprise-Standalone-x64.exe) or defenseclaw.exe enterprise windowsSYSTEM or an elevated administrator
Z1The DefenseClawHookGuardian, DefenseClawHookEnumerator and DefenseClawSensorHelper servicesLocalSystem. The sensor helper keeps only SeChangeNotifyPrivilege.
Z2The DefenseClawGateway service, listening on 127.0.0.1:18970. It writes only runtime and logs\gateway under C:\ProgramData\Cisco\DefenseClaw, and its IPC directory C:\Program Files\Cisco\DefenseClaw\ipc.NT SERVICE\DefenseClawGateway
Z3Binaries in C:\Program Files\Cisco\DefenseClaw\bin. Under C:\ProgramData\Cisco\DefenseClaw: etc\config.yaml, secrets, hook-guardian\targets.yaml (target manifest), hook-guardian-state (authorization ledger) and install (lifecycle state). Hook runtime state in C:\ProgramData\Cisco\DefenseClaw-HookRuntime. Vendor machine policy in %ProgramData%\OpenAI\Codex\requirements.toml, C:\Program Files\ClaudeCode\managed-settings.d, %ProgramData%\Cursor\hooks.json, %ProgramData%\GitHub\Copilot\policy.d and %ProgramData%\opencode.Written only by Administrators and SYSTEM
Z4The AI agent; defenseclaw-hook.exe, an administrator-owned binary that runs as the user; the user's agent config and DefenseClaw hook registrationsThe signed-in user
Z5Cisco AI DefenseExternal

On Windows the guardian writes a user's files under that user's own token, and only while the user has an active (connected) session. On Windows the lifecycle writes Codex requirements.toml at install, upgrade and repair; the guardian writes the Claude Code, Cursor, Copilot and OpenCode machine policy and repairs all five. Windows hooks reach the gateway over loopback TCP with credentials bound to the user's SID.

A few Windows files are readable by standard users by design: the lifecycle results in %WINDIR%\Logs\DefenseClaw, and the per-connector enrollment lists, runtime selectors and public machine-policy summary in C:\ProgramData\Cisco\DefenseClaw-HookRuntime. They hold no credential.

Linux

systemd units
owned entries
worker as the user
loaded by
runs
Unix socket · uid check
local socket
read-only
HTTPS · optional
TrustedZ0 · Admin and MDM (root)
PrivilegedZ1 · Services (root)
ProtectedZ3 · Admin-owned files
UntrustedZ4 · User session (untrusted)
RestrictedZ2 · Gateway (defenseclaw)
ExternalZ5 · Cloud (external)
OperatorMDM or adminenterprise linux
SystemHook guardianhook enumerator
SystemSensor helper
PolicyConfig · policiessecrets · ledger
PolicyVendor machinepolicy
Agent runtimeAI agentuser config · hooks
Connectordefenseclaw-hook
Control planedefenseclaw-gateway
SystemCisco AI Defense
Linux. An arrow that crosses a zone border is a trust boundary; its label names the channel.
ZoneWhat runs or lives thereIdentity
Z0systemd (PID 1), the package manager, and defenseclaw-gateway enterprise linux run by an MDM script, an administrator, the config-apply path unit or the daily verify timerroot
Z1The defenseclaw-hook-guardian, defenseclaw-hook-enumerator and defenseclaw-sensor-helper services. For each user, the guardian starts a short-lived worker that runs as that user.root, each service with a fixed, reduced capability set. The worker runs as the target user.
Z2The defenseclaw-gateway service. systemd owns its two sockets, 127.0.0.1:18970 and /run/defenseclaw-hook/hook.sock, and keeps them open across gateway restarts. The gateway can write only /var/lib/defenseclaw, /run/defenseclaw, /var/log/defenseclaw and its hook socket directory /run/defenseclaw-hook.The defenseclaw system user, with no capabilities
Z3/opt/defenseclaw/bin; /etc/defenseclaw with config.yaml, policies, secrets, hook-guardian/targets.yaml and managed-runtime.json; /var/lib/defenseclaw-hook-guardian (authorization ledger); /var/lib/defenseclaw-enterprise (lifecycle state). Vendor machine policy in /etc/codex/requirements.toml, /etc/claude-code/managed-settings.d, /etc/cursor/hooks.json, /etc/github-copilot/policy.d and /etc/opencode.Written only by root
Z4The AI agent; /opt/defenseclaw/bin/defenseclaw-hook running as the user; the user's agent configThe user
Z5Cisco AI DefenseExternal

On Linux and macOS the lifecycle, not the guardian, writes vendor machine policy. Hooks, DefenseClaw's in-agent plugins and bridges reach the gateway only through the hook socket, which gives the gateway each caller's kernel uid; there is no TCP fallback.

macOS

LaunchDaemons
owned entries
worker as the user
loaded by
runs
Unix socket · uid check
local socket
read-only
HTTPS · optional
TrustedZ0 · Admin and MDM (root)
PrivilegedZ1 · Services (root)
ProtectedZ3 · Admin-owned files
UntrustedZ4 · User session (untrusted)
RestrictedZ2 · Gateway (_defenseclaw)
ExternalZ5 · Cloud (external)
OperatorMDM or adminenterprise macos
SystemHook guardianhook enumerator
SystemSensor helper
PolicyConfig · policiessecrets · ledger
PolicyVendor machinepolicy
Agent runtimeAI agentuser config · hooks
Connectordefenseclaw-hook
Control planedefenseclaw-gateway
SystemCisco AI Defense
macOS. An arrow that crosses a zone border is a trust boundary; its label names the channel.
ZoneWhat runs or lives thereIdentity
Z0launchd, the .pkg installer, and defenseclaw-gateway enterprise macos run by the MDM agent, an administrator, or the com.cisco.defenseclaw.apply and com.cisco.defenseclaw.verify LaunchDaemonsroot
Z1The com.cisco.defenseclaw.hook-guardian, com.cisco.defenseclaw.hook-enumerator and com.cisco.defenseclaw.sensor-helper LaunchDaemons. For each user, the guardian starts a short-lived worker that runs as that user.root. The worker runs as the target user.
Z2The com.cisco.defenseclaw.gateway LaunchDaemon, listening on 127.0.0.1:18970 and /opt/cisco/defenseclaw/run/hook.sock. It writes only /opt/cisco/defenseclaw/runtime, its socket directory /opt/cisco/defenseclaw/run, and /Library/Logs/Cisco/DefenseClaw/gateway._defenseclaw, a hidden system user
Z3Under /opt/cisco/defenseclaw: bin, etc/config.yaml, etc/policies, etc/secrets, etc/hook-guardian/targets.yaml, etc/managed-runtime.json, hook-guardian-state (authorization ledger) and lifecycle. Vendor machine policy in /etc/codex/requirements.toml, /Library/Application Support/ClaudeCode/managed-settings.d, /Library/Application Support/Cursor/hooks.json, /etc/github-copilot/policy.d and /Library/Application Support/opencode.Written only by root
Z4The AI agent; /opt/cisco/defenseclaw/bin/defenseclaw-hook running as the user; the user's agent configThe user
Z5Cisco AI DefenseExternal

What a standard user can and cannot do

The tables list what happens when a standard user, or an AI agent running as that user, tries to get around DefenseClaw. The results mean:

  • Denied: the operating system or DefenseClaw refuses the action.
  • Still inspected: the change is accepted, but DefenseClaw's hooks keep running.
  • Repaired: the guardian puts DefenseClaw's registration back.
  • Fails closed: the agent's tool call is blocked with a DefenseClaw message.

A result applies to every OS unless the cell names one.

Disable DefenseClaw

AttemptResultEnforced by
Stop, disable, delete or reconfigure a DefenseClaw service (sc.exe, Stop-Service, systemctl stop, disable or mask, launchctl bootout)DeniedWindows: service permissions give users query rights only. Linux: the units are root-owned and changing them needs root. macOS: system LaunchDaemons need root.
End a DefenseClaw processDeniedThe services run as LocalSystem, root or the gateway account, which a standard user cannot signal. Each service also restarts whenever it exits: Windows service recovery repeats indefinitely, systemd uses Restart=always, and launchd uses KeepAlive.
Replace, rename, truncate or change the permissions of a DefenseClaw binary, or plant a link in its directoriesDeniedBinaries and every parent directory are writable only by administrators or root.
Edit the config, policies, secrets, target manifest, authorization ledger, runtime descriptor, service definitions or vendor machine policyDeniedAdministrator-only write on each file and its parent directory. The gateway itself has read-only access, and the loader rejects config and policy files a non-administrator could have written.
Read the Cisco AI Defense API keyDeniedLinux: the key file is readable only by root (systemd 247 or later passes it to the gateway as a credential), or by root and the defenseclaw group on older systemd. macOS: readable by root and the _defenseclaw group. Windows: readable by SYSTEM, Administrators and the gateway service only.
Start a per-user gateway, or run defenseclaw upgrade, defenseclaw rollback or the per-user installerRefusedThey detect the managed deployment and refuse. Windows: install.ps1, upgrade and rollback check the HKLM\SOFTWARE\Cisco\DefenseClaw\Enterprise marker, and the per-user gateway checks the recorded managed deployment. Linux and macOS: the runtime descriptor. This check prevents accidental conflicts; defenseclaw-hook still verifies the listener.

Impersonate the gateway

AttemptResultEnforced by
Listen on 127.0.0.1:18970, or on the hook socket, while an administrator restarts the gateway, and answer "allow"Fails closed: the listener receives no hook request, credential or tool payload. Two exceptions, in Residual risks: the agents' own telemetry exporters, and on Windows a listener that takes the port between the Amp or OpenCode plugin's listener check and its hook call.Peer verification. Windows: defenseclaw-hook sends only when the listening process is the running DefenseClawGateway service, and the Amp and per-user OpenCode plugins first require the listener to prove it can derive the user's credential. Linux: systemd keeps both sockets open across restarts, and hooks and plugins use only the hook socket and check that the listener is root or defenseclaw. macOS: hooks and plugins use only the socket, in a directory only _defenseclaw can write, and check the listener's uid.
Create the hook socket, or its directory, before the service startsDeniedLinux: /run/defenseclaw-hook is created at boot for defenseclaw with mode 0755. macOS: /opt/cisco/defenseclaw/run belongs to _defenseclaw inside the root-owned install tree. Windows has no hook socket.

Disable hooks

AttemptResultEnforced by
Delete or edit DefenseClaw's hook registration or plugin in your own agent config (per-user connectors)Repaired within about a minute; a file change usually triggers repair within secondsThe guardian watches the files and reconciles every minute, writing as the user. Windows: repair runs while the user has an active (connected) session.
Turn hooks off in user or project settings: Claude Code disableAllHooks (also through --settings), Codex [features] hooks = false, -c features.hooks=false or --disable hooksStill inspectedMachine policy. Claude Code runs managed hooks whatever lower settings say. Codex machine requirements pin features.hooks = true and managed hooks only.
Point the agent at another config directory with CLAUDE_CONFIG_DIR, HOME, CODEX_HOME or COPILOT_HOMEStill inspectedCodex, Claude Code and Copilot load DefenseClaw's hooks from fixed machine paths, not from the user's config directory.
Start a per-user agent (Devin, Antigravity, Hermes, Amp, OpenHands, OmniGent) with another config home, such as XDG_CONFIG_HOME, HOME or HERMES_HOME, with devin --config <file>, or with Hermes --safe-modeNot inspected, not logged, not repaired; status and verify still report the user's agent readyDefenseClaw's registration is only in the default location, and the guardian cannot see how a session was started. See Residual risks.
Run a copy of a supported agent, at a supported version, from another pathStill inspectedMachine policy applies to every copy of Codex, Claude Code, Cursor, Copilot and OpenCode on the computer. An old or self-built client can ignore it; see Residual risks.
Change DefenseClaw's own environment, such as DEFENSECLAW_FAIL_MODE=open or another gateway address or tokenStill inspected, or fails closeddefenseclaw-hook in a managed deployment always fails closed, never open, and talks only to a gateway it has verified. Linux and macOS: it reads the gateway address and listener identity only from the administrator-owned runtime descriptor. Windows: it checks that the listener is the DefenseClawGateway service process.

A client that DefenseClaw does not support, or one that is too old or modified, is not covered. See Residual risks.

Weaken security

AttemptResultEnforced by
Add a user or project hook for Codex or Claude Code that rewrites a tool call after DefenseClaw checked itDenied for both on every OS; the hook never runs.The vendor's managed-hooks-only lock (allow_managed_hooks_only for Codex, allowManagedHooksOnly for Claude Code), set in machine policy.
Change DefenseClaw's configuration or policy through the gateway API, or use one agent's hook token for another agentDeniedThe management API needs the gateway's own token, which users cannot read. A hook token works only on its own agent's hook routes, and the hook socket serves only the hook, inspect and Codex notify routes, never the management API.
Delete or edit DefenseClaw's audit database, lifecycle state or logsDeniedThese live in administrator- or service-owned directories.

Affect another user

AttemptResultEnforced by
Change or replace another user's agent config, DefenseClaw registration or project filesDeniedHome directory permissions. DefenseClaw writes each user's files as that user, so it never writes with more rights than the user has.
Read another user's DefenseClaw hook token or authorization ledger rowsDeniedEach user's copy of a hook token is in that user's own files with owner-only access, and in the gateway's private state. The ledger is administrator-owned and readable only by administrators and the gateway.
Send hook or telemetry requests that claim to be another userDeniedLinux and macOS hooks: the gateway takes the caller's identity from the kernel (the peer uid on the hook socket), not from the request. On TCP (Windows hooks, and telemetry on every OS): each user's credential is bound to their uid or SID, and the gateway refuses identity headers that name anyone else.
Plant a rewriting Codex or Claude Code hook in a shared project directory that another user works inDenied for both on every OS; the hook never runs.The vendor's managed-hooks-only lock.
Enroll, exempt or remove another userDeniedThe target manifest and authorization ledger are administrator-owned. Only administrators (through the lifecycle), the enumerator and the guardian write them, from the administrator's config.
Gain administrator rights through DefenseClaw, for example through a writable service path or a hijacked PATHDeniedBinaries and directories are administrator-owned. The lifecycle uses fixed paths and ignores the caller's PATH and environment, and each service takes its environment only from its service definition.

How each boundary is protected

Each row is one boundary from the diagrams, with the control that defends it.

BoundaryWhat could go wrongControl
Z0 to Z1 and Z3: the lifecycle installs services and filesA tampered or user-writable payload runs with administrator rightsTrusted payloads. Windows: Setup and defenseclaw.exe enterprise windows accept only an Authenticode-signed payload or one that matches a pinned SHA-256 manifest, and run PowerShell 7 only from its protected registration; enterprise.trust.mode: authenticode also refuses the hash-pinned route. Linux and macOS: the MDM script checks a pinned SHA-256, or the package signature, before it installs. Every lifecycle action is a locked transaction that rolls back on failure, and an older release is refused unless the administrator asks for a rollback.
Z4 to Z1, Z2 and Z3: a user acts on services or filesA user stops a service, replaces a binary, or edits config, policy, secrets, the manifest or the ledgerService hardening and administrator-only ACLs. Windows services give users query rights only; Linux units and macOS LaunchDaemons are root-owned; every service restarts when it exits. Every DefenseClaw file and its parent directory is writable only by administrators or root, except the gateway's own state and log directories, which its service account writes. A deployment record or folder a standard user plants under %ProgramData% is ignored or moved aside.
Z4 to Z2: the hook calls the gatewayA user process takes the gateway's address during a restart and answers "allow"Peer verification. defenseclaw-hook sends no bytes until the listener is proven. Windows: the connected process must be the running DefenseClawGateway service process. The Windows Amp plugin and the per-user OpenCode plugin, which call the gateway from inside the agent, first make the listener prove it can derive the user's credential (an HMAC over a fresh nonce), so an impostor that answers the proof receives only a digest and the call fails closed. The proof is a separate request from the hook call that follows: a listener that takes the gateway's place between the two, which needs an administrator or upgrade restart at that moment and a new connection for the hook call, receives that call's credential and payload, and its answer is accepted. See Residual risks. Linux and macOS: hooks, DefenseClaw's in-agent plugins and bridges use only the hook socket, and the listener must be root (systemd) or the gateway account. There is no TCP fallback. Otherwise the call fails closed. The agents' own telemetry exporters do not verify the listener; see Residual risks.
Z2 authorizing Z4: the gateway accepts a hook callAn unenrolled user, or another user's identity, reaches inspectionLinux and macOS: the gateway reads the caller's kernel uid on the hook socket. A per-user agent requires that uid to be enrolled for that agent in the authorization ledger. Agents attached through machine policy are inspected for every user unless enterprise.enrollment.unenrolled_users is deny. Root follows enterprise.enrollment.root. On the TCP address (Windows hooks, and every OS's telemetry exporters), each user's credentials are bound to their uid or SID and accepted only while the ledger protects that user; the gateway attributes the request to that identity and refuses identity headers that name anyone else. Each credential works only on its own agent's routes. Windows: a user who is not in the protected enrollment state fails closed.
Z1 to Z4: the guardian repairs a user's filesA privileged service is tricked into writing outside the user's home, or a registration stays deletedGuardian and enumerator. The guardian writes as the user: under the user's own token on Windows, and through a worker process running as the user on Linux and macOS. It repairs changes within about a minute and records each protected user in the ledger. The enumerator refreshes enrollment every 5 minutes. On Linux and macOS it removes a user only after three consecutive definite "no such user" answers, so a directory outage removes no one. On Windows a revoked user's DefenseClaw registrations are removed as that user, at their next sign-in if they are signed out.
Z3 to Z4: vendor machine policy loads DefenseClaw's hooksA user turns hooks off or points the agent at another configMachine policy. For Codex, Claude Code, Cursor, Copilot and OpenCode (through DefenseClaw's managed OpenCode plugin), DefenseClaw's hooks sit in the vendor's machine-wide policy, which a standard user cannot edit. DefenseClaw adds only its own entries and removes only those on uninstall. On Windows it rewrites Codex requirements.toml as normalized TOML, so comments and key order in that file are not kept. See Machine policy.
Inside Z4: a user or project hook runs next to DefenseClaw'sA second hook rewrites or approves the tool call after inspectionVendor lock and foreign-hook guard. Codex and Claude Code run with the vendor's managed-hooks-only lock under the default managed_hooks_only: enforce (Codex always on Windows). For Cursor, Copilot, Devin, OpenCode and Amp, Hermes on Linux and macOS, and Codex or Claude Code with managed_hooks_only: preserve, the foreign-hook guard removes unapproved entries from the user's config, and defenseclaw-hook denies tool calls while an unapproved hook is present in the user's files or the project. A session that started while an unapproved hook was present stays denied until the agent restarts, for at most 7 days, because agents keep the hooks they loaded at session start; the gateway keeps that record per verified uid or SID, and stop and session-end events are still allowed so the agent can end its turn.
Z2 to Z5: the gateway calls Cisco AI DefenseThe API key leaksThe key is read only from the protected secrets directory, never logged or printed, and an API key written in the config is rejected. The call uses HTTPS, through enterprise.network when a proxy is set. Without a key, the local policy engine decides alone. See AI Defense key.

These rules hold on every OS:

  • The gateway never runs as root or LocalSystem.
  • No privileged service writes a user's files with its own rights.
  • defenseclaw-hook sends nothing to a listener it has not verified.
  • The authorization ledger, not a status file, decides who is protected.
  • A directory lookup error never removes a user.
  • Paths come from the fixed layout, never from the caller's environment.
  • Secrets are never logged or printed.
  • A running service is not proof of protection. Status reports partial coverage as incomplete.

Scope

Inspected

DefenseClaw inspects the hook events that supported agents send: tool calls, and for some agents prompts and session events. It protects only the agents listed in the config. On Linux and macOS, listing a machine-policy agent publishes its policy even with enabled: false, and the config the lifecycle writes when you supply none lists no agents. On Windows you supply the config. See Choose the agents to protect.

AgentHow DefenseClaw is attachedWindowsLinuxmacOS
Codex, Claude Code, Cursor, GitHub CopilotVendor machine policyYesYesYes
OpenCodeVendor machine policy, through DefenseClaw's managed OpenCode plugin; per user while that plugin is not in forceYesYesYes
Devin, Antigravity, HermesHook registration in each user's configYesYesYes
AmpPlugin in each user's configYesYesYes
OpenHands, OmniGentRegistration in each user's configNot supportedYesYes
KiroLinux and macOS: hook registration in each user's global ~/.kiro/hooks and the CLI 2.x defenseclaw agent. Windows: the ACP guard, defenseclaw-gateway enterprise acp, when the agent runs through itACP onlyYesYes
OpenClaw, ZeptoClawNot supported: they need DefenseClaw's model-traffic proxy, which the enterprise profile does not runNoNoNo

Which users are protected is set by enrollment. See Enrollment.

Not covered

  • Agents that are not in the table above.
  • Self-built, modified or copied agent clients, and clients below DefenseClaw's supported minimum version.
  • A per-user agent started with a config home other than the user's default or in a mode that skips user configuration (Hermes --safe-mode), a per-user agent below its supported minimum version (for example OpenHands before 1.12.0 started with uvx), and agents installed where discovery does not look. See Residual risks.
  • Agents that run in a container, a virtual machine, WSL, a dev container or on a remote host. Hooks run where the agent runs, so DefenseClaw must be installed there.
  • Anything an agent does outside the events it sends to its hooks. The enterprise profile does not proxy or inspect the agent's network or model traffic.
  • Administrators and root, who are trusted.

Residual risks

These risks remain by design or because of how an agent vendor works.

RiskWhereWhat reduces it
Per-user agents are advisory against a deliberate user. DefenseClaw's registration or plugin lives in the user's own default config. A user can remove it until the guardian repairs it (usually within seconds, at most about a minute), and can start the agent with another config home (for example XDG_CONFIG_HOME, HOME, OPENCODE_CONFIG_DIR, HERMES_HOME or a non-default Hermes profile), with devin --config <file>, or with Hermes --safe-mode, so the registration is never loaded: no DefenseClaw hook runs, nothing fails closed, no audit record is written, and the guardian never repairs that session. Status and verify keep reporting the user's agent ready, because the registration in the default location is intact. On Linux and macOS a user can also leave a path the guardian refuses in their own home, such as a link or a file where the agent's config folder belongs; the registration is then not repaired until the path is fixed, and status and verify report it only as the warning guardian_target_user_path, which does not fail verify or detect.sh --require-healthy. This applies to Amp (XDG_CONFIG_HOME, HOME), Devin (XDG_CONFIG_HOME, --config), Antigravity and OpenHands (HOME), and Hermes (--safe-mode, HERMES_HOME). Machine-policy agents are not affected.Devin, Antigravity, Hermes, Amp, OpenHands, OmniGent, and OpenCode while it is on the per-user routePrefer agents that use machine policy where you need enforcement. Use application control to control how users launch these agents, for example by allowing the agent to run only from an administrator-owned launcher that resets these variables and refuses these flags, or a vendor machine policy where the agent has one.
Unsupported, old, copied or self-built clients. A client below DefenseClaw's hook-contract floors, or one built without the vendor's machine-policy handling, can ignore machine policy and hooks. For Claude Code the standalone profile sets requiredMinimumVersion (the version floor), but Claude Code reads it only from 2.1.163, so builds older than that, including every build below the 2.1.154 floor, ignore it: the floor stops no build (2.1.153 starts with it in place). No other connector has a vendor setting that stops an older client. For builds from 2.1.163, running sessions continue until the next session start, an administrator value wins even below the floor, and a value that is not a version merging after DefenseClaw's drop-in leaves no floor. While HKLM Settings, macOS managed preferences or server-managed settings are in force without the key, the builds it targets never read it. enterprise policy verify fails when a value, file or source it can see leaves no floor, and reports a value below the floor. On Linux and macOS, Claude Code releases that do not read managed-settings.d (for example 1.0.128, 2.0.0 and 2.0.77) ignore both DefenseClaw drop-ins, the hooks and the floor: a user who installs one under their home runs it with no DefenseClaw hook and no audit record, and status and verify do not report it. Tracked in #920. Per-user agents below their supported minimum are the same: OpenHands 1.11.0 (the minimum is 1.12.0), started with uvx --from openhands==1.11.0 openhands, does not load DefenseClaw's hooks, so its tool calls run with no audit record. Nothing refuses it, and because uvx runs it from its cache, it is not reported either.Every OSUse application control (WDAC or AppLocker on Windows, fapolicyd on Linux, Santa or similar on macOS) to allow only approved agent clients at or above the supported versions, including copies that a package runner such as uvx starts from its cache. Put requiredMinimumVersion in any higher-precedence Claude Code source you deploy.
Agents installed in unusual places. Discovery covers the usual install locations, the common Node version managers and package managers, and agent_prefixes. An agent installed or copied anywhere else in a home is neither enrolled nor reported.Every OSInstall shared agents under an agent_prefixes path (Linux and macOS); use application control.
Hook process control. defenseclaw-hook and the per-user hook scripts run as the user, so that user can end, suspend or slow them until the agent's hook timeout. Agents that block only on an explicit deny or exit code then run the call, and no DefenseClaw decision or audit record is written before it runs. Claude Code and Codex run the call when the user kills their own hook (a failed hook) or stops it (a 30-second timeout), and OpenHands, Devin and Hermes run it when the hook is killed. OpenHands can also run it when the hook stalls until its 60-second timeout, leaving only OpenHands' own confirmation prompt, which the user answers. GitHub Copilot stays closed unless every one of its hooks is stopped, and OpenCode, Amp and Antigravity stay closed. "Fail-closed" in the capability matrix means blocking when the hook cannot reach the gateway, not when the user ends the hook.Every OSUse EDR process protection or application control so users cannot signal the hook; keep hook latency low and monitor hook failures, and tool calls that appear in the audit without a pre-tool decision (for example a Hermes post_tool_call record with no pre_tool_call record).
Windows repairs need a session. The guardian writes a user's files only while that user has an active (connected) session, so a user who is signed out or disconnected is repaired when their session is active again. Revoked users are cleaned at their next sign-in.Windows, per-user agentsMonitor guardian status for users that stay pending.
Windows uninstall leaves the DefenseClaw per-user registrations of users who are signed out at the time, and of every user when it does not run as LocalSystem. The result lists them (user_registrations_pending). They are inert: enrollment is revoked and the hook binary is removed, and none of these agents blocks on a hook command that cannot start.Windows, per-user agentsUninstall from your MDM as LocalSystem while users are signed in.
Claude Code --bare and CLAUDE_CODE_SIMPLE=1 skip the managed SessionStart and UserPromptSubmit hooks. The managed PreToolUse hook still runs, so tool calls are still inspected. disableAllHooks, including through --settings, does not turn off managed hooks.Claude Code, every OSTreat prompt and session inspection as advisory. Tool-call inspection is the enforcement point.
The Windows Claude Code attestation is the administrator's statement. repair --attest-claude-effective-policy records it; it does not run Claude Code.Windows, Claude CodeBefore you attest, have Claude Code make a tool call in an enrolled user's own session and find its record with audit export from an elevated prompt (enterprise policy verify --live is refused on a managed Windows host); repeat after each upgrade.
Agents without a lock or the guard. Antigravity, OpenHands and OmniGent have neither, and neither has Hermes on Windows, so hooks a user or project adds for them run next to DefenseClaw's.Those agents, every OS; Hermes on WindowsTreat their coverage as advisory; use application control where you need more.
Hermes has no hook lock or ordering. On Linux and macOS the foreign-hook guard blocks tool calls while config.yaml, or the managed-scope config.yaml a user points HERMES_MANAGED_DIR at, has a hook DefenseClaw did not write, but a Hermes process keeps the hooks it loaded at start or re-read on a plugin reload: an entry the user removes after Hermes loaded it and before the next session start or tool call keeps running in that process unseen (one the guardian removes keeps that process's tool calls blocked until Hermes restarts). Hermes Python plugins run inside Hermes and are not inspected.Hermes, Linux and macOSTreat Hermes coverage as advisory; use application control over Hermes plugins and how users launch Hermes.
OpenHands project hooks replace DefenseClaw's. OpenHands loads a project's .openhands/hooks.json instead of the user's ~/.openhands/hooks.json: it uses the first of the two it finds, so in a project that has its own file, even one with a single unrelated hook, none of DefenseClaw's OpenHands hooks run. Tool calls there are not inspected or logged, OpenHands shows no DefenseClaw message, and status and verify do not report it. A repository a developer clones can carry the file.OpenHands, Linux and macOSTreat OpenHands coverage as advisory. Keep .openhands/hooks.json out of the repositories developers use (for example with a repository rule or a server-side push check), search existing checkouts for it, and use application control where you need more.
The foreign-hook guard's session block holds only a hook present when the session started, or one the guardian removed after the agent process started (only for a process DefenseClaw can name). A foreign hook that removes itself before DefenseClaw's session-start check, a hook added later in the session, or a session still running 7 days after its block was recorded is held only by the per-call check, which denies while the hook is present. The guardian cleans a redirected user config location only after a DefenseClaw hook has run with that environment; on Windows it also cleans the locations the user's persistent environment names, while the user's registry hive is loaded.Agents the foreign-hook guard covers, every OSFor Claude Code and Codex on Linux and macOS, keep the vendor lock (managed_hooks_only: enforce). Deliver hooks your developers need through machine policy.
Amp has no machine-wide plugin location, and the order in which it loads plugins is not defined. The DefenseClaw plugin sits in the user's default Amp config directory, so an Amp session that uses a different config directory (for example with XDG_CONFIG_HOME or HOME set to another folder) does not load it: tool calls there run with no audit record, and status and verify still report the user's Amp ready.Amp, every OSTreat Amp coverage as best effort. Use application control over how users launch Amp, as for other per-user agents.
OpenCode can start without plugins. Pure mode (--pure, OPENCODE_PURE=1) and OPENCODE_TEST_MANAGED_CONFIG_DIR start a session without any DefenseClaw plugin, the managed one included, and OpenCode does not document the order in which plugins run.OpenCode, every OSThe foreign-hook guard stays on for OpenCode. Recheck after each OpenCode release.
Cursor applies the enterprise hooks.json only on plans that support enterprise hooks.Cursor, every OSConfirm on a real client with your Cursor plan.
Kiro per-user hooks are advisory against a deliberate user, like every per-user agent. Only Kiro IDE 1.0.182 and later and kiro-cli --v3 read the global ~/.kiro/hooks file. Neither kiro-cli engine vetoes prompts: kiro-cli 2.24.1 with --v3 sends a prompt DefenseClaw blocked to the model with the block reason attached (the audit log still records the block), and bare kiro-cli (the 2.x engine) vetoes tool calls only, and only through the defenseclaw agent. Another agent (--agent, /agent swap), a relocated KIRO_HOME, or hooks from Kiro's cloud configuration sync run without DefenseClaw's hook. Kiro proceeds past any hook exit other than 0 and 2, and its hook timeout is not documented.Kiro, Linux and macOSKeep kiro-cli at 2.24.1 or later. Treat a kiro-cli prompt block as a record, not a veto. Turn off configuration sync in the Kiro console. Use the ACP guard for editors that start Kiro over ACP.
Kiro on Windows is covered only when it runs through the ACP guard. The Windows guardian does not enroll Kiro, so an editor entry or terminal that starts it directly is not controlled, and coverage depends on the user-side setup step. A per-user Kiro hook returns a block as exit 2 when Kiro starts it through cmd.exe or directly; Kiro does not document its Windows hook shell, and a powershell -Command launcher reports the block as 1, which Kiro proceeds past.Kiro, WindowsSee ACP guard and Kiro on Windows.
Agents used only as a desktop app or editor extension are not enrolled. Enrollment finds an agent only through its CLI install, so a user of Claude Desktop, the Claude Code or Codex VS Code extension, the Codex app or the Antigravity IDE who has no CLI install gets no enrollment: on Windows their machine-policy hook calls are refused, on Linux and macOS they are inspected under the default contract or refused (unenrolled_users), and per-user agents get no hooks. Tracked in #912.Every OSInstall the agent's CLI for app users, or set unenrolled_users: deny.
GitHub Copilot in VS Code (the Local agent harness) is not covered. It does not read Copilot's machine policy, and DefenseClaw has no VS Code hook route yet. Tracked in #913.Copilot in VS Code, every OSUse the Copilot CLI for governed work, or restrict VS Code agent mode with VS Code's enterprise policies.
Agent sessions inside WSL 2 are outside Windows machine policy: Claude Desktop WSL sessions, the Codex app's WSL agent and the Codex VS Code extension's WSL mode. The user can be root in their own distribution, and Windows endpoint sensors do not see the WSL VM. Tracked in #914.WindowsTurn WSL off (AllowWSL=0) where agents must be governed.
Devin Desktop is not covered. A user without the devin CLI is not enrolled, Devin Local under devin acp is not certified, and builds before 3.9.19 still run Cascade. Tracked in #915.Devin Desktop, every OSKeep Devin Desktop at 3.9.19 or later; use application control over which apps users run.
The Kiro IDE is not discovered and has no version floor. Kiro IDE 1.0.182 and later should read the global hook file the guardian writes on Linux and macOS, but that is not live-verified, and older IDE builds read only workspace hooks. Tracked in #916.Kiro IDE, every OSKeep Kiro IDE at 1.0.182 or later; use the ACP guard for editors that start Kiro over ACP.
Hermes blocks a tool call only when the hook returns a block answer (and, from Hermes 0.21, exit code 2), so a hook that crashes or is killed cannot fail closed, and in the Hermes releases DefenseClaw supports a hook timeout lets the call run too. Some Hermes builds block the call when a stalled hook times out, but Hermes does not document that. GitHub Copilot command hooks that time out fail open.Hermes, CopilotTreat Hermes coverage as advisory. Use EDR process protection or application control so users cannot signal the hook. Keep hook latency low and monitor timeouts.
Availability. A user can hold the gateway's address while the gateway is stopped. defenseclaw-hook then fails closed, which blocks that user's tool calls, and does not accept an "allow" from that listener. On Linux, systemd keeps the sockets open across normal restarts.Every OSMonitor gateway health.
Availability under a hook flood. Each account has its own hook budget (see enterprise_managed_rate_limited in Troubleshooting) and runs at most half as many requests at once as the gateway has processors, so one account's flood is refused or queued without stopping other accounts' hooks. It still makes their hooks slower: the gateway accepts and refuses the flood's connections, and the flooding account's own processes compete for the host's CPU, which DefenseClaw does not control.Standalone profile, every OSLimit standard users' CPU (on Linux, for example, CPUQuota= on user.slice), and find what floods the gateway from the account named in the rate-limit log line.
Windows plugin listener check. The Windows Amp plugin and the per-user OpenCode plugin check the listener with a separate request before each hook call. A user who takes 127.0.0.1:18970 between that check and the hook call receives that call's per-user credential and tool payload, and the plugin accepts the answer. It needs the gateway to release the port at that moment (an administrator or upgrade restart) and the hook call to open a new connection. defenseclaw-hook checks the service process on every connection and is not affected.Windows, Amp and per-user OpenCodeRestart or upgrade the gateway outside working hours; alert on any process other than the gateway listening on 127.0.0.1:18970.
Telemetry to a held port. The agents' own telemetry exporters send to 127.0.0.1:18970 without verifying the listener. A user who holds the port while the gateway is down receives that telemetry, which can include prompt text, and the sending user's per-user telemetry credential, and can then post telemetry attributed to that user for that agent until the user leaves enrollment. The credential never authenticates hook, inspect or management routes, or another agent.Codex, Claude Code, OpenHands and OmniGent telemetry. Every gateway restart on macOS and Windows; on Linux only while an administrator has the socket unit stoppedAlert on any process other than the gateway listening on 127.0.0.1:18970, and treat per-user telemetry attribution as advisory after a gateway restart.
In the Secure Client profile hook and telemetry credentials are shared per agent, so one user can post events attributed to another user of the same agent.Secure Client profile, Windows and macOSTreat per-user attribution in Secure Client telemetry as advisory.
Group filters on Windows use cached membership. A signed-out user is decided from the groups seen at their last sign-in, and a directory user who has not signed in since installation is pending: kept, not added, not revoked.Windows, include_groups and exclude_groupsName groups by SID; allow for the next sign-in when you change membership.
User namespaces on Linux. Where standard users can create a private user and mount namespace, an agent started inside one can be given its own view of the machine policy, the runtime descriptor and the hook socket directory. enterprise linux verify warns (unprivileged_user_namespaces), as it does on stock Ubuntu 24.04 and RHEL 9.LinuxSet user.max_user_namespaces=0, or on AppArmor hosts kernel.apparmor_restrict_unprivileged_unconfined=1, for example in /etc/sysctl.d. Both also restrict the Codex and Claude Code command sandboxes; see User namespaces.
Administrator actions have short windows. A running gateway can reload an edited config just before the lifecycle rejects and reverts it, and on Linux an upgrade that changes a socket unit releases the gateway's port while the socket restarts.Linux and macOSChange the config and upgrade through the lifecycle, and monitor config_rejected.
A higher-precedence vendor policy, such as Codex cloud or MDM requirements or Claude Code server-managed settings, can override the local machine policy.Codex, Claude CodeCoordinate with whoever manages those settings, and check the effective policy with defenseclaw-gateway enterprise policy verify --live --user <user> --connector <codex or claudecode> --agent-binary <absolute path>, run as root or an administrator with DEFENSECLAW_CONFIG set to the managed config (see Machine policy).
Unsigned, hash-pinned builds do not satisfy application-control rules that require a publisher signature.Windows (WDAC, AppLocker), macOS (Gatekeeper)Use signed builds, or re-sign them and pin your certificate with the trust options at install time.
A compromised privileged DefenseClaw service holds administrator-level power.Every OSKeep binaries administrator-owned; the services are part of the trusted base.

Full threat models

The repository models carry one row per threat, with the code and tests behind each control: