Secure Client managed deployment

How DefenseClaw runs as a Cisco Secure Client module on Windows and macOS, what it installs, and how to install, reconcile, verify, upgrade and remove it. The standalone profile is documented in the Enterprise section.

This page covers the Secure Client profile of a managed deployment: DefenseClaw installed as a module of Cisco Secure Client on Windows or macOS. In this profile Cisco AI Defense makes every decision and the local detectors are off (Secure Client profile). For any other MDM, use the standalone profile and start with Deploy to a fleet.

Not using Secure Client?

To deploy DefenseClaw with Intune, Jamf, Iru (formerly Kandji), Workspace ONE, configuration management or a package on Windows, Linux or macOS, use the standalone profile in Enterprise deployment. That section also has the concepts, the threat model, the rollout plan and the Linux deployment. The Secure Client profile is not supported on Linux.

What is the same in both profiles

The two profiles share the design described in Enterprise deployment: a gateway service, a privileged hook guardian that installs and repairs each enrolled user's hooks, an enumerator that finds the users to protect, and a sensor helper for AI Discovery. The config sets deployment_mode: managed_enterprise, belongs to the administrator, and runtime HTTP PATCH changes are rejected. What a standard user can and cannot do is the same; see Who can change what and the threat model.

What is specific to the Secure Client profile:

SettingSecure Client profile
PlatformsWindows (x64) and macOS (Apple silicon)
Who decides on each tool callCisco AI Defense, authenticated with the Secure Client machine identity (CMID). The local detectors are off
Configenterprise.profile is the only enterprise.* key allowed; every other enterprise setting belongs to the standalone profile and is rejected
Default profileWhen neither the config nor the service environment sets a profile, Windows and macOS resolve to secure_client
WindowsFive services, including the CMID credential broker, installed by DefenseClawSetup-Enterprise-x64.exe with Windows PowerShell 5.1
macOSRoot LaunchDaemons under /opt/cisco/secureclient/defenseclaw
One profile per computerThe profiles share the gateway port and, on Windows, the service names. The standalone lifecycle refuses to install over a Secure Client deployment

Enterprise service enforcement is opt-in. Installing a release that contains Windows enterprise support does not create a machine service, move state into ProgramData, harden user files, or give hook ownership to the guardian; that happens only when an administrator runs the enterprise lifecycle with a managed config. Both modes repair hook drift: normal mode uses the existing per-user repair loop, while managed mode moves repair to the administrator-owned guardian, which a standard user cannot unregister or reconfigure.

Windows system-service layout

A Secure Client deployment on Windows runs five Service Control Manager (SCM) services. The standalone profile has the same services without the broker, its own roots and a PowerShell 7 lifecycle; see Windows standalone deployment.

ServiceIdentityPurpose
DefenseClawGatewayNT SERVICE\DefenseClawGateway virtual service account, only SeChangeNotifyPrivilegeInspection, policy, audit, the loopback hook API and health
DefenseClawCMIDBrokerLocalSystem, only SeChangeNotifyPrivilegeHolds access to the Secure Client machine-identity provider behind a gateway-only IPC channel
DefenseClawSensorHelperLocalSystem, only SeChangeNotifyPrivilegeAnswers the gateway's fixed AI Discovery requests (process, connection, host-event and DNS observations). A request carries no path, pid, filter or command
DefenseClawHookGuardianLocalSystemImpersonates each enrolled user to install and repair that user's hooks, then returns to LocalSystem for protected state
DefenseClawHookEnumeratorLocalSystemFinds eligible users in HKLM ProfileList and maintains the protected target manifest

The AI agent runs as the interactive standard user. It invokes the hooks but cannot stop, reconfigure or replace any of these services.

runs per tool call
asks over loopback TCP
token, named pipe
asks, local socket
inspects, HTTPS
UntrustedZ4 · User session (the user)
RestrictedZ2 · Gateway (virtual account)
PrivilegedZ1 · Services (LocalSystem)
ExternalZ5 · Cloud
AI agentruns as the user
defenseclaw-hook.exechecks the listener
Gatewayallows or blocks
CMID brokerholds machine identity
Sensor helperanswers AI Discovery
Cisco AI Defensedecides each call

List view for small screens. Use the expand button to open the drawing.

UntrustedZ4 · User session (the user)

  1. AI agentruns as the user
    • runs per tool calldefenseclaw-hook.exe
  2. defenseclaw-hook.exechecks the listener
    • asks over loopback TCPGatewayZ2

RestrictedZ2 · Gateway (virtual account)

  1. Gatewayallows or blocks
    • token, named pipeCMID brokerZ1
    • asks, local socketSensor helperZ1
    • inspects, HTTPSCisco AI DefenseZ5

PrivilegedZ1 · Services (LocalSystem)

  1. Sensor helperanswers AI Discovery
  2. CMID brokerholds machine identity

ExternalZ5 · Cloud

  1. Cisco AI Defensedecides each call
Windows, Secure Client profile. The hook asks the gateway on 127.0.0.1:18970 after it has checked that the listener is the DefenseClawGateway service. The gateway runs as a virtual account with no access to the machine identity: it asks the LocalSystem CMID broker for a token over a gateway-only named pipe, then sends the call to Cisco AI Defense, which decides. The sensor helper answers fixed AI Discovery requests over a local socket. The guardian and enumerator, which keep each user's hooks in place, are shown in the Windows standalone deployment.
ItemPath
Binaries (broker, gateway, sensor helper, hook, ACP adapter, lifecycle CLI)C:\Program Files\Cisco\Cisco Secure Client\DefenseClaw\bin
Lifecycle scriptsC:\Program Files\Cisco\Cisco Secure Client\DefenseClaw\libexec\install-enterprise.ps1 and DefenseClawEnterprise.psm1
Managed configC:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\etc\config.yaml
Runtime state and service-side scoped credentialsC:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\runtime
LogsC:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\logs
Target manifestC:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\hook-guardian\targets.yaml
Authorization ledgerC:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\hook-guardian-state\protected_targets.json
Deployment recordC:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\install\deployment.json
IPC sockets (Secure Client UI, sensor helper)C:\Program Files\Cisco\Cisco Secure Client\DefenseClaw\ipc\
Codex machine policyC:\ProgramData\OpenAI\Codex\requirements.toml
Claude Code machine policyC:\Program Files\ClaudeCode\managed-settings.d\90-defenseclaw.json

The roots are fixed. They come from the protected 64-bit machine registration in HKLM, not from the caller's environment, and the lifecycle refuses roots on network, substituted or aliased drives, reparse points, unsafe owners and unsafe DACLs. Environment poisoning therefore cannot redirect a deployment.

Windows enrollment and discovery

DefenseClawHookEnumerator walks HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList 30 seconds after it starts and then every five minutes, and rewrites targets.yaml only when its content changes. It considers interactive-user SIDs (S-1-5-21-…) with a valid, reparse-free profile path, and only the connector families enabled in the managed config. A new user and connector pair is enrolled once a supported agent and version are found in that profile, so a user who installs a supported agent is enrolled on the next cycle. Rows an administrator already set (enabled, deferred, agent_version) are kept.

The enumerator also grants the gateway service read access to the connector folders it inventories (.claude, .codex, .cursor, .agents, .config), not to the whole profile. A folder that cannot be granted is logged and retried on the next cycle.

Install the Windows services

Secure Client delivers DefenseClawSetup-Enterprise-x64.exe, a single signed Setup that embeds eight files: defenseclaw-cmid-broker.exe, defenseclaw-gateway.exe, defenseclaw-hook.exe, defenseclaw-acp.exe, defenseclaw-sensor-helper.exe, defenseclaw.exe (the lifecycle CLI), install-enterprise.ps1 and DefenseClawEnterprise.psm1. Setup must run elevated. It stages the files in a folder only SYSTEM and Administrators can write, verifies each embedded digest, and runs the enterprise lifecycle.

$Stage = 'C:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw-Staging'
.\DefenseClawSetup-Enterprise-x64.exe /install JSON=1 `
  CONFIG="$Stage\config.yaml" `
  MANIFEST="$Stage\targets.yaml"
ActionWhat it does
/installFirst install. Requires CONFIG= and MANIFEST=
/upgradeReplace the payload with this release, transactionally
/repairRestore files, DACLs and services; also applies a new CONFIG= or MANIFEST=
/reconcileRun one guardian reconcile now
/status, /verifyReport state; verify also checks every file, DACL and service and fails on any problem
/uninstallRemove the services and binaries. Add PURGE=1 to remove managed state too

Other properties: NOSTART=1 installs with the services disabled and stopped (activate later with /repair, never with Start-Service), ATTESTAGENTAPPLICATIONCONTROL=1 and ATTESTCLAUDEEFFECTIVEPOLICY=1 record the attestations described below, and TIMEOUTSECONDS= bounds the run. The Secure Client Setup exits 0 on success and 1603 on any failure, including a run that rolled back. It has no /ensure action and no ALLOWEDSIGNERS=; those belong to the standalone Setup.

An administrator can drive the same transaction with the installed CLI, defenseclaw enterprise windows <action> --installer <path> --json. It validates the installer and module before it starts the in-box PowerShell engine with a clean environment. Build, signing and handoff details are in the repository's Windows enterprise Setup guide.

The config and first manifest

A Secure Client config. Quote Windows paths in YAML:

config_version: 8
deployment_mode: managed_enterprise
data_dir: 'C:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\runtime'
observability:
  local:
    path: 'C:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\runtime\audit.db'
    judge_bodies_path: 'C:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\runtime\judge_bodies.db'
  defaults:
    redaction_profile: sensitive
plugin_dir: 'C:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\runtime\plugins'
policy_dir: 'C:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\runtime\policies'
gateway:
  device_key_file: 'C:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\runtime\device.key'
  api_bind: 127.0.0.1
  api_port: 18970
  config_reload:
    mode: restart
guardrail:
  enabled: true
  mode: observe
  scanner_mode: both
application_protection:
  enabled: false

Keep application_protection.enabled: false: in managed mode the guardian, not the gateway, writes user hooks. The first manifest lists the users and connectors to enroll; the enumerator maintains it afterwards. For domain or renamed accounts, add the exact sid:

version: 1
targets:
  - user: alice
    connector: codex
    agent_version: "codex-cli 0.144.3"
  - user: CONTOSO\bob
    sid: S-1-5-21-111111111-222222222-333333333-1001
    connector: claudecode
    agent_version: "2.1.207 (Claude Code)"

Claude Code proof and security_complete

Install is phase one. A fresh install reports claude_effective_policy_verified=false and security_complete=false while a Claude Code target is enabled. Run the approved Claude Code client as an enrolled user with disableAllHooks set in the user and project settings. When you see DefenseClaw's managed hooks run (or the client block the call), record the proof with /repair ATTESTCLAUDEEFFECTIVEPOLICY=1. The proof is bound to the manifest's hash, so a manifest change clears it.

ATTESTAGENTAPPLICATIONCONTROL=1 is optional. Pass it only after WDAC or AppLocker is deployed and tested to allow approved agent builds and block old and unsigned ones. Without it, the managed hooks still run.

The version floors on Windows are Codex 0.131.0 and Claude Code 2.1.152.

Reconcile and verify Windows targets

User hooks are written only by DefenseClawHookGuardian. It takes the enrolled user's active session token, writes that user's files as that user, and fails when the user has no active session. Do not run enterprise hooks install, reconcile or watch from an elevated shell. Run one service-mediated reconcile before you accept an endpoint:

$Gateway = 'C:\Program Files\Cisco\Cisco Secure Client\DefenseClaw\bin\defenseclaw-gateway.exe'
$Manifest = 'C:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\hook-guardian\targets.yaml'

& $Gateway enterprise windows reconcile --json
& $Gateway enterprise hooks status --manifest $Manifest --json
& $Gateway enterprise hooks verify --manifest $Manifest --json

reconcile restarts the guardian and waits for its startup reconcile. The status and verify output has an ok field; a partial reconcile makes both return ok: false and a non-zero exit. verify checks the service inputs, authorization coverage, hook command, native config, helpers and tokens.

After the first successful reconcile, the guardian watches the enrolled footprints and also reconciles periodically. It repairs deleted or edited hook entries, helpers, scoped tokens and supported native config, replaces a target-owned link or extra hard link with a canonical file, and resets the managed DACLs. Foreign-owned objects, unsafe parents and path escapes stay failures. Repair is not instant: measure the recovery time for each approved agent, and use WDAC, AppLocker, MDM or EDR where a file must be immutable.

A hook sends nothing until it has checked that the process listening on the loopback port is the running DefenseClawGateway service, so another process on port 18970 never receives a token or a request, and its reply is never treated as an allow.

Verify Windows service hardening

From an elevated shell:

$Services = 'DefenseClawGateway', 'DefenseClawCMIDBroker', 'DefenseClawSensorHelper',
  'DefenseClawHookGuardian', 'DefenseClawHookEnumerator'
Get-CimInstance Win32_Service |
  Where-Object { $Services -contains $_.Name } |
  Select-Object Name, State, StartMode, StartName, PathName
foreach ($Service in $Services) { sc.exe qc $Service; sc.exe qfailure $Service; sc.exe sdshow $Service }
.\DefenseClawSetup-Enterprise-x64.exe /verify JSON=1

Expect the identities in the table above, automatic start, the Secure Client image paths, three restart failure actions (5 s, 15 s, then 60 s), protected DACLs with no standard-user write entry, and a passing /verify. The full certification procedure, including live token and tamper checks, is in the repository's Windows enterprise certification runbook. Run it only on disposable validation endpoints.

Windows repair, upgrade, and removal

Run every change through the lifecycle, from a fresh copy of the release's Setup:

  • Upgrade. /upgrade with the approved CONFIG= and MANIFEST=. A failed validation leaves the previous deployment running; a failed activation rolls back. The services are disabled and drained before files change, so an SCM restart cannot revive a half-replaced deployment.
  • Change the config or manifest. /repair CONFIG=... MANIFEST=.... The lifecycle replaces and re-verifies the protected files and restarts the services in order.
  • Remove. /uninstall revokes the targets, removes the services and binaries, and removes DefenseClaw's Codex and Claude Code machine-policy entries. It keeps runtime state, logs and guardian evidence. PURGE=1 also removes managed state; use it only for an approved decommission. This is the Secure Client profile: the standalone Setup's /uninstall always removes its machine state (see Remove).

After an upgrade, run /status, /verify, the guardian status and verify above, and one allowed and one blocked tool call.

Removal never deletes C:\ProgramData\OpenAI\Codex, C:\Program Files\ClaudeCode or managed-settings.d. It removes only the entries DefenseClaw owns, and fails rather than overwrite a value an administrator changed. Restart Codex and Claude Code sessions afterwards: a session that was already running may still call the removed hook binary. The uninstall result reports cached_enterprise_clients_require_reload: true.

A standard user cannot make a removal stick by editing the manifest, the ledger or a hook: the guardian repairs the declared targets. To stop managing one user, disable their row in the manifest, apply it with /repair, then remove DefenseClaw's native entries with that user's own token (an MDM action or the connector's teardown). The one elevated exception is removing an already-owned Claude Code machine-policy registration, shown below.

Native Windows Codex managed hooks

Codex is enrolled through machine policy, not by editing <profile>\.codex\config.toml. The lifecycle owns C:\ProgramData\OpenAI\Codex\requirements.toml with allow_managed_hooks_only = true, hooks enabled, and the ten hook events (SessionStart, UserPromptSubmit, PreToolUse, PermissionRequest, PostToolUse, SubagentStart, SubagentStop, PreCompact, PostCompact, Stop). Each hook command runs the protected defenseclaw-hook.exe through the fixed System32 Windows PowerShell, so a user's PATH, config or project hooks cannot change it. Users can read the policy but not write it. The lifecycle creates C:\ProgramData\OpenAI\Codex when it is missing and never takes over an existing folder.

The guardian verifies and repairs the policy bytes, events, owner and DACL. A missing event, a deleted policy or DACL drift makes status and verify fail until it is repaired. Read-only check:

& $Gateway enterprise windows codex-requirements verify --json

For the standalone profile, see Machine policy.

Native Windows Claude Code managed hooks

Claude Code is enrolled without writing ~/.claude/settings.json. Add the claudecode target to the manifest and run the service-mediated reconcile above. The guardian writes the user's scoped runtime under <profile>\.defenseclaw as that user, then publishes the machine policy C:\Program Files\ClaudeCode\managed-settings.d\90-defenseclaw.json with allowManagedHooksOnly: true. Claude Code loads it without a hook trust prompt.

  • The policy applies to every user on the machine, but a hook call from a user whose SID is not enrolled is refused before any credential is read. Test this with a second, unenrolled standard account.
  • The per-user runtime is always <profile>\.defenseclaw. The managed hook ignores DEFENSECLAW_HOME and CLAUDE_CONFIG_DIR.
  • DefenseClaw refuses to overwrite a foreign drop-in, a drop-in an administrator edited, disableAllHooks: true, a file policy superseded by policyHelper, or a higher-precedence HKLM policy. In those environments, add the DefenseClaw hooks to the policy source that wins (server-managed, then HKLM/MDM, then the Program Files file, then HKCU).
  • The policy file existing is not proof that it takes effect. Use the proof step in Claude Code proof and security_complete.

To remove one user's already-owned registration after disabling their row and reconciling, an elevated administrator can run the installed gateway:

& $Gateway enterprise hooks uninstall --user alice --connector claudecode --json

If the account is gone, pass the recorded --sid S-1-5-21-... instead of --user. The per-user runtime files stay behind, inert.

For the standalone profile, see Machine policy.

macOS LaunchDaemon layout

On macOS the Secure Client module runs as root LaunchDaemons, because the machine-identity provider needs root to read its credential store. There is no dedicated defenseclaw service user on macOS. The standalone macOS package is different (it runs the gateway as _defenseclaw under /opt/cisco/defenseclaw); see macOS standalone deployment.

LaunchDaemonRunsPurpose
com.cisco.secureclient.defenseclawThe gateway, as rootInspection, policy, audit, hook API and health
com.cisco.secureclient.defenseclaw.hook-guardianenterprise hooks watch, as root, KeepAliveWatches the enrolled footprints and reconciles every 60 seconds
com.cisco.secureclient.defenseclaw.hook-enumeratorrender-targets.sh, every 300 secondsRewrites the target manifest from the local users
PathOwnerMode
/opt/cisco/secureclient/defenseclawroot:wheel0755
/opt/cisco/secureclient/defenseclaw/bin/defenseclaw-gatewayroot:wheel0755
/opt/cisco/secureclient/defenseclaw/etcroot:wheel0755
/opt/cisco/secureclient/defenseclaw/etc/config.yamlroot:wheel0640
/opt/cisco/secureclient/defenseclaw/runtimeroot:wheel0750
/opt/cisco/secureclient/defenseclaw/hook-guardianroot:wheel0750
/opt/cisco/secureclient/defenseclaw/hook-guardian/targets.yamlroot:wheel0640
/opt/cisco/secureclient/defenseclaw/hook-guardian-stateroot:wheel0750
/Library/Logs/Cisco/SecureClient/DefenseClawroot:wheel0750
/Library/LaunchDaemons/com.cisco.secureclient.defenseclaw*.plistroot:wheel0644

The gateway bundle (defenseclaw-macos-<version>-darwin-arm64) carries the module's install.sh and uninstall.sh and the three plists. For an administrator-staged config and manifest, the release also ships packaging/launchd/install-enterprise.sh, which installs the gateway and guardian daemons:

sudo ./packaging/launchd/install-enterprise.sh \
  --binary ./defenseclaw \
  --config /path/to/approved-config.yaml \
  --manifest /path/to/approved-targets.yaml

It is idempotent, refuses symlinked sources and destinations, checks the root-owned path chain, keeps runtime state across reinstalls, and verifies the owners and modes above before launchd starts a job. The runtime directory is the config's data_dir, and hook-guardian-state holds the authorization ledger. Before replacing files it snapshots the deployment and records which jobs are loaded. A failure after jobs are stopped restores the previous binary, config, manifest, and plists, then re-bootstraps only the jobs that were loaded before. --no-start installs without loading the jobs.

launchd has no equivalent of the Linux systemd sandbox. Protect the module with code-signing and notarization policy, MDM file ownership, Endpoint Security or EDR, and restricted local administrator membership.

Verify:

sudo launchctl print system/com.cisco.secureclient.defenseclaw
sudo launchctl print system/com.cisco.secureclient.defenseclaw.hook-guardian
sudo lsof -nP -iTCP:18970 -sTCP:LISTEN
sudo tail -n 100 /Library/Logs/Cisco/SecureClient/DefenseClaw/gateway.err.log
sudo tail -n 100 /Library/Logs/Cisco/SecureClient/DefenseClaw/hook-guardian.err.log

Restart-required controls

In managed mode, config.yaml is the only live configuration source. Hot reload applies only observability, sink, webhook, notification and identity-metadata fields. Connector topology, listeners, scanners, policies and other enforcement settings need a service restart; gateway.config_reload.mode: restart makes that the default. Apply a change through the administrator channel:

  • Windows. /repair CONFIG=... MANIFEST=... with the Setup, then /verify. Do not use the per-user CLI or HTTP PATCH.
  • macOS. Edit the config, then restart both daemons:
sudoedit /opt/cisco/secureclient/defenseclaw/etc/config.yaml
sudo launchctl kickstart -k system/com.cisco.secureclient.defenseclaw
sudo launchctl kickstart -k system/com.cisco.secureclient.defenseclaw.hook-guardian

For the standalone profile, see Change the config.

Sandbox policy pushdown

The openshell.admin block is documented in Sandbox policy pushdown. In the Secure Client profile, apply a change to it as shown in Restart-required controls; on macOS the gateway reloads the openshell block without a restart.

Troubleshooting

SymptomLikely causeWhat to do
security_complete is false on WindowsClaude Code is enabled and its proof is not recorded, or no supported target is enabledSee Claude Code proof
One user's target failsThe user has no active session, their native config is missing, or a file in the footprint is foreign-owned or unsafeRead the target's error in enterprise hooks status --json; fix the file's provenance instead of changing owners or modes repeatedly
HTTP 401 from one connector's hookIts scoped token is missing, unreadable or driftedRun /repair or a reconcile. Connectors have separate tokens; do not share one
AI Discovery reports sensor helper (not started)DefenseClawSensorHelper is stopped or its socket DACL is unhealthyRun /verify, then /repair. Do not edit the service or socket by hand
The per-user installer or defenseclaw upgrade refusesA managed deployment existsUpdate through Secure Client

For exit codes and error codes shared with the standalone profile, see Troubleshooting. If an AI agent gained administrator rights, treat the endpoint as compromised; see Contain an incident.

Production checklist

  • AI agent users are standard users without administrator rights or passwordless sudo.
  • The Setup and its eight inner files are the signed release; the broker uses the signed Secure Client provider library.
  • The config, manifest and ledger have administrator-only path chains.
  • The enumerator's manifest lists only expected users and approved connectors.
  • The first reconcile succeeds for every enabled target before any connector moves to action mode.
  • On Windows, the Claude Code proof is recorded and security_complete is true.
  • Monitoring alerts on guardian errors, connector errors, repeated repair and enforcement downgrade.
  • Allowed and blocked tool calls, and the measured hook-repair time, are recorded for the deployed version.
  • MDM or EDR locks native agent config where repair-after-tamper is not enough.
  • Upgrades and incident response use an administrator channel the AI agent cannot reach.