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:
| Setting | Secure Client profile |
|---|---|
| Platforms | Windows (x64) and macOS (Apple silicon) |
| Who decides on each tool call | Cisco AI Defense, authenticated with the Secure Client machine identity (CMID). The local detectors are off |
| Config | enterprise.profile is the only enterprise.* key allowed; every other enterprise setting belongs to the standalone profile and is rejected |
| Default profile | When neither the config nor the service environment sets a profile, Windows and macOS resolve to secure_client |
| Windows | Five services, including the CMID credential broker, installed by DefenseClawSetup-Enterprise-x64.exe with Windows PowerShell 5.1 |
| macOS | Root LaunchDaemons under /opt/cisco/secureclient/defenseclaw |
| One profile per computer | The 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.
| Service | Identity | Purpose |
|---|---|---|
DefenseClawGateway | NT SERVICE\DefenseClawGateway virtual service account, only SeChangeNotifyPrivilege | Inspection, policy, audit, the loopback hook API and health |
DefenseClawCMIDBroker | LocalSystem, only SeChangeNotifyPrivilege | Holds access to the Secure Client machine-identity provider behind a gateway-only IPC channel |
DefenseClawSensorHelper | LocalSystem, only SeChangeNotifyPrivilege | Answers the gateway's fixed AI Discovery requests (process, connection, host-event and DNS observations). A request carries no path, pid, filter or command |
DefenseClawHookGuardian | LocalSystem | Impersonates each enrolled user to install and repair that user's hooks, then returns to LocalSystem for protected state |
DefenseClawHookEnumerator | LocalSystem | Finds 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.
List view for small screens. Use the expand button to open the drawing.
UntrustedZ4 · User session (the user)
- AI agentruns as the user
- runs per tool calldefenseclaw-hook.exe
- defenseclaw-hook.exechecks the listener
- asks over loopback TCPGatewayZ2
RestrictedZ2 · Gateway (virtual account)
- Gatewayallows or blocks
- token, named pipeCMID brokerZ1
- asks, local socketSensor helperZ1
- inspects, HTTPSCisco AI DefenseZ5
PrivilegedZ1 · Services (LocalSystem)
- Sensor helperanswers AI Discovery
- CMID brokerholds machine identity
ExternalZ5 · Cloud
- Cisco AI Defensedecides each call
| Item | Path |
|---|---|
| Binaries (broker, gateway, sensor helper, hook, ACP adapter, lifecycle CLI) | C:\Program Files\Cisco\Cisco Secure Client\DefenseClaw\bin |
| Lifecycle scripts | C:\Program Files\Cisco\Cisco Secure Client\DefenseClaw\libexec\install-enterprise.ps1 and DefenseClawEnterprise.psm1 |
| Managed config | C:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\etc\config.yaml |
| Runtime state and service-side scoped credentials | C:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\runtime |
| Logs | C:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\logs |
| Target manifest | C:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\hook-guardian\targets.yaml |
| Authorization ledger | C:\ProgramData\Cisco\Cisco Secure Client\DefenseClaw\hook-guardian-state\protected_targets.json |
| Deployment record | C:\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 policy | C:\ProgramData\OpenAI\Codex\requirements.toml |
| Claude Code machine policy | C:\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"| Action | What it does |
|---|---|
/install | First install. Requires CONFIG= and MANIFEST= |
/upgrade | Replace the payload with this release, transactionally |
/repair | Restore files, DACLs and services; also applies a new CONFIG= or MANIFEST= |
/reconcile | Run one guardian reconcile now |
/status, /verify | Report state; verify also checks every file, DACL and service and fails on any problem |
/uninstall | Remove 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: falseKeep 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 --jsonreconcile 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=1Expect 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.
/upgradewith the approvedCONFIG=andMANIFEST=. 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.
/uninstallrevokes 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=1also removes managed state; use it only for an approved decommission. This is the Secure Client profile: the standalone Setup's/uninstallalways 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 --jsonFor 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 ignoresDEFENSECLAW_HOMEandCLAUDE_CONFIG_DIR. - DefenseClaw refuses to overwrite a foreign drop-in, a drop-in an
administrator edited,
disableAllHooks: true, a file policy superseded bypolicyHelper, or a higher-precedenceHKLMpolicy. In those environments, add the DefenseClaw hooks to the policy source that wins (server-managed, thenHKLM/MDM, then the Program Files file, thenHKCU). - 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 --jsonIf 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.
| LaunchDaemon | Runs | Purpose |
|---|---|---|
com.cisco.secureclient.defenseclaw | The gateway, as root | Inspection, policy, audit, hook API and health |
com.cisco.secureclient.defenseclaw.hook-guardian | enterprise hooks watch, as root, KeepAlive | Watches the enrolled footprints and reconciles every 60 seconds |
com.cisco.secureclient.defenseclaw.hook-enumerator | render-targets.sh, every 300 seconds | Rewrites the target manifest from the local users |
| Path | Owner | Mode |
|---|---|---|
/opt/cisco/secureclient/defenseclaw | root:wheel | 0755 |
/opt/cisco/secureclient/defenseclaw/bin/defenseclaw-gateway | root:wheel | 0755 |
/opt/cisco/secureclient/defenseclaw/etc | root:wheel | 0755 |
/opt/cisco/secureclient/defenseclaw/etc/config.yaml | root:wheel | 0640 |
/opt/cisco/secureclient/defenseclaw/runtime | root:wheel | 0750 |
/opt/cisco/secureclient/defenseclaw/hook-guardian | root:wheel | 0750 |
/opt/cisco/secureclient/defenseclaw/hook-guardian/targets.yaml | root:wheel | 0640 |
/opt/cisco/secureclient/defenseclaw/hook-guardian-state | root:wheel | 0750 |
/Library/Logs/Cisco/SecureClient/DefenseClaw | root:wheel | 0750 |
/Library/LaunchDaemons/com.cisco.secureclient.defenseclaw*.plist | root:wheel | 0644 |
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.yamlIt 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.logRestart-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-guardianFor 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
| Symptom | Likely cause | What to do |
|---|---|---|
security_complete is false on Windows | Claude Code is enabled and its proof is not recorded, or no supported target is enabled | See Claude Code proof |
| One user's target fails | The user has no active session, their native config is missing, or a file in the footprint is foreign-owned or unsafe | Read 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 hook | Its scoped token is missing, unreadable or drifted | Run /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 unhealthy | Run /verify, then /repair. Do not edit the service or socket by hand |
The per-user installer or defenseclaw upgrade refuses | A managed deployment exists | Update 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_completeistrue. - 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.
Configure a standalone deployment
Where the standalone enterprise config lives on Windows, Linux and macOS, the keys every config needs, how to choose the AI agents to protect, every enterprise setting with its default, and how the network proxy works.
Enrollment
How the enumerator picks the users and agents to protect on Windows, Linux and macOS, the filters you can set, and what happens when users change.