by motiful
AI API identity gateway — reverse proxy that normalizes device fingerprints and telemetry for privacy-preserving API proxying
# Add to your Claude Code skills
git clone https://github.com/motiful/cc-gatewayAlpha — This project is under active development. Test with a non-primary account first.
Disclaimer — This software is provided for security research and privacy auditing purposes. It is the user's responsibility to comply with applicable terms of service. The authors assume no liability for misuse.
Claude Code collects 640+ telemetry event types across 3 parallel channels, fingerprints your machine with 40+ environment dimensions, and phones home every 5 seconds. Your device ID, email, OS version, installed runtimes, shell type, CPU architecture, and physical RAM are all reported to the vendor — continuously.
If you run Claude Code on multiple machines, each device gets a unique permanent identifier. There is no built-in way to manage how your identity is presented to the API.
CC Gateway is a reverse proxy that sits between Claude Code and the Anthropic API. It normalizes device identity, environment fingerprints, and process metrics to a single canonical profile — giving you control over what telemetry leaves your network.
user_id JSON blob in every API request are normalized to one canonical identityenv object is swapped, not patched<env> block injected into every prompt (Platform, Shell, OS Version, working directory) is rewritten to match the canonical profile, preventing cross-reference detection between telemetry and prompt contentconstrainedMemory), heap size, and RSS are masked to canonical values so hardware differences don't leakplatform.claude.com and never need a browser loginbaseUrl and gateway fields that would reveal proxy usage in analytics eventsgit clone https://github.com/motiful/cc-gateway.git
cd cc-gateway
npm install
# Generate canonical identity
npm run generate-identity
# Generate a client token
npm run generate-token my-machine
# Configure
cp config.example.yaml config.yaml
# Edit config.yaml: paste device_id, client token, and OAuth refresh_token
bash scripts/extract-token.sh
# Copies refresh_token from macOS Keychain → paste into config.yaml
# Development (no TLS)
npm run dev
# Production
npm run build && npm start
# Docker
docker-compose up -d
# Health check
curl http://localhost:8443/_health
# Rewrite verification (shows before/after diff)
curl -H "Authorization: Bearer <your-token>" http://localhost:8443/_verify
Add these environment variables on each client machine. No browser login needed.
# Route all Claude Code traffic through the gateway
export ANTHROPIC_BASE_URL="https://gateway.your-domain.com:8443"
# Disable side-channel telemetry (Datadog, GrowthBook, version checks)
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
# Skip browser OAuth — gateway handles authentication
export CLAUDE_CODE_OAUTH_TOKEN="gateway-managed"
# Authenticate to the gateway
export ANTHROPIC_CUSTOM_HEADERS="Proxy-Authorization: Bearer YOUR_TOKEN"
Or run the interactive setup script:
bash scripts/client-setup.sh
Then start Claude Code normally — claude — no login prompt, traffic routes through the gateway automatically.
| Layer | Field | Action |
|-------|-------|--------|
| Identity | device_id in metadata + events | → canonical ID |
| | email | → canonical email |
| Environment | env object (40+ fields) | → entire object replaced |
| Process | constrainedMemory (physical RAM) | → canonical value |
| | rss, heapTotal, heapUsed | → randomized in realistic range |
| Headers | User-Agent | → canonical CC version |
| | Authorization | → real OAuth token (injected by gateway) |
| | x-anthropic-billing-header | → canonical fingerprint |
| Prompt text | Platform, Shell, OS Version | → canonical values |
| | Working directory | → canonical path |
| | /Users/xxx/, /home/xxx/ | → canonical home prefix |
| Leak fields | baseUrl (ANTHROPIC_BASE_URL) | → stripped |
| | gateway (provider detection) | → stripped |
Clash acts as a network-level safety net. Even if Claude Code bypasses env vars or adds new hardcoded endpoints in a future update, Clash blocks direct connections.
rules:
- DOMAIN,gateway.your-domain.com,DIRECT # Allow gateway
- DOMAIN-SUFFIX,anthropic.com,REJECT # Block direct API
- DOMAIN-SUFFIX,claude.com,REJECT # Block OAuth
- DOMAIN-SUFFIX,claude.ai,REJECT # Block OAuth
- DOMAIN-SUFFIX,datadoghq.com,REJECT # Block telemetry
See clash-rules.yaml for the full template.
Client machines CC Gateway Anthropic
┌────────────┐ ┌──────────────────┐
│ Claude Code │── ANTHROPIC_ ────│ Auth: Bearer │
│ + env vars │ BASE_URL │ OAuth: auto- │
│ + Clash │ │ refresh │──── single ────▶ api.anthropic.com
│ (blocks │ │ Rewrite: all │ identity
│ direct) │ │ identity │
└────────────┘ │ Stream: SSE │
│ passthrough │
└──────────────────┘
│
platform.claude.com
(token refresh only,
from gateway IP)
Defense in depth:
| Layer | Mechanism | What it prevents |
|-------|-----------|-----------------|
| Env vars | ANTHROPIC_BASE_URL + DISABLE_NONESSENTIAL + OAUTH_TOKEN | CC voluntarily routes to gateway, disables side channels, skips browser login |
| Clash | Domain-based REJECT rules | Any accidental or future direct connections to Anthropic |
| Gateway | Body + header + prompt rewriting | All 40+ fingerprint dimensions normalized to one device |
mcp-proxy.anthropic.com is hardcoded and does not follow ANTHROPIC_BASE_URL. If clients use official MCP servers, those requests bypass the gateway. Use Clash to block this domain if MCP is not needed.extract-token.sh on the admin machine.This project builds on:
No comments yet. Be the first to share your thoughts!