The wrapper
When you runclaude, it’s actually cac’s wrapper at ~/.cac/bin/claude (which is first in PATH). The wrapper:
Fingerprint spoofing layers
Layer 1: Shell shims
~/.cac/shim-bin/ contains scripts that intercept system commands:
Shims only intercept targeted calls. All other invocations pass through to the real command.
Layer 2: Node.js hooks
fingerprint-hook.js is injected via NODE_OPTIONS --require and monkey-patches:
os.hostname()→CAC_HOSTNAMEos.networkInterfaces()→ fake MAC fromCAC_MACos.userInfo()→CAC_USERNAMEfs.readFileSync('/etc/machine-id')→CAC_MACHINE_ID
Layer 3: Environment variables
Identity values are also exported as env vars (CAC_HOSTNAME, CAC_MAC, CAC_MACHINE_ID, CAC_USERNAME) so they’re available to any child process.
Telemetry blocking
DNS-level
cac-dns-guard.js intercepts Node.js DNS resolution and fetch() to block:
statsig.anthropic.comsentry.io/sentry-cdn.comsegment.io/segment.com- Other known telemetry endpoints
Environment variable level
12 env vars are set to disable telemetry across multiple frameworks:HOSTALIASES
~/.cac/blocked_hosts maps telemetry domains to 0.0.0.0 via the HOSTALIASES environment variable.
mTLS
Each environment has a client certificate signed by cac’s self-signed CA. The CA cert is trusted viaNODE_EXTRA_CA_CERTS. This provides an additional authentication layer between the wrapper and any services that verify client certificates.
Config isolation
CLAUDE_CONFIG_DIR is set to ~/.cac/envs/<name>/.claude/. This means:
- Sessions are per-environment
- Settings are per-environment
- Project memory is per-environment
- Auth tokens are per-environment
cac work vs cac personal gives you completely separate Claude Code experiences.