Skip to content

eddiedunn/anthropic-proxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

anthropic-proxy

Transparent reverse proxy for Claude Code API calls to api.anthropic.com.

What It Does

anthropic-proxy sits between Claude Code (or any Anthropic API client) and api.anthropic.com, forwarding all requests over HTTPS with HTTP/2. It provides request metrics, token tracking, a live dashboard, and an optional secret scrubber that detects and pseudonymizes credentials before they reach the upstream API.

Quick Start

# Install dependencies (requires uv)
make install

# Generate a self-signed TLS certificate
openssl req -x509 -newkey rsa:2048 -keyout server.key -out server.crt \
  -days 365 -nodes -subj "/CN=localhost"

# Run locally
make run

The proxy listens on https://127.0.0.1:8443 by default. Point your client at this address instead of https://api.anthropic.com.

Configuration

All settings are controlled via environment variables prefixed with ANTHROPIC_PROXY_. Pydantic Settings handles parsing and validation.

Core

Variable Default Description
ANTHROPIC_PROXY_HOST 0.0.0.0 Bind address
ANTHROPIC_PROXY_PORT 8443 HTTPS listen port
ANTHROPIC_PROXY_DASHBOARD_PORT 9090 Plain HTTP port for the dashboard
ANTHROPIC_PROXY_SHUTDOWN_TIMEOUT 30.0 Seconds to wait for active requests to drain on shutdown

Logging

Variable Default Description
ANTHROPIC_PROXY_LOG_LEVEL info Python log level (debug, info, warning, error)
ANTHROPIC_PROXY_LOG_REQUESTS false Log every proxied request/response
ANTHROPIC_PROXY_LOG_SLOW_THRESHOLD 5.0 Seconds; requests slower than this are logged at WARNING

Upstream

Variable Default Description
ANTHROPIC_PROXY_UPSTREAM_BASE_URL https://api.anthropic.com Upstream API base URL
ANTHROPIC_PROXY_UPSTREAM_CONNECT_TIMEOUT 10.0 TCP connect timeout (seconds)
ANTHROPIC_PROXY_UPSTREAM_READ_TIMEOUT 300.0 Read timeout (seconds)
ANTHROPIC_PROXY_UPSTREAM_WRITE_TIMEOUT 30.0 Write timeout (seconds)
ANTHROPIC_PROXY_UPSTREAM_POOL_TIMEOUT 10.0 Connection pool timeout (seconds)
ANTHROPIC_PROXY_UPSTREAM_MAX_CONNECTIONS 20 Max concurrent connections to upstream
ANTHROPIC_PROXY_UPSTREAM_MAX_KEEPALIVE_CONNECTIONS 10 Max keepalive connections in pool

Secret Scrubber

Variable Default Description
ANTHROPIC_PROXY_SCRUB_MODE off off or pseudonymize
ANTHROPIC_PROXY_SCRUB_HMAC_KEY (empty) 64-char hex key for HMAC pseudonymization
ANTHROPIC_PROXY_SCRUB_MAX_BODY_SIZE 10485760 Max request body size to scrub (bytes; 10 MB)

Secret Scrubber

The scrubber intercepts POST request bodies, detects secrets and identifiers using regex-based detectors, and replaces them with deterministic placeholders before forwarding to the upstream API.

Enabling

Set two environment variables:

ANTHROPIC_PROXY_SCRUB_MODE=pseudonymize
ANTHROPIC_PROXY_SCRUB_HMAC_KEY=<64-char hex key>

Key Generation

python3 -c "import secrets; print(secrets.token_hex(32))"

Detectors

The scrubber runs 16 detectors in priority order. Earlier detectors take precedence on overlapping matches.

# Detector Example Match Tier
1 anthropic_key sk-ant-api03-abc... SECRET
2 openai_key sk-proj-abc123... SECRET
3 aws_access_key AKIAIOSFODNN7EXAMPLE SECRET
4 github_token ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx SECRET
5 google_api_key AIzaSyA1234567890abcdefghijklmnopqrstuv SECRET
6 stripe_key sk_live_abc123def456ghi789... SECRET
7 private_key -----BEGIN RSA PRIVATE KEY----- SECRET
8 jwt eyJhbGci...eyJzdWIi...signature SECRET
9 db_connection_string postgres://user:pass@host/db SECRET
10 bearer_token Bearer eyJhbGciOiJIUz... SECRET
11 basic_auth Basic dXNlcjpwYXNz... SECRET
12 sonarqube_token sqp_a1b2c3d4e5f6... SECRET
13 jenkins_api_token 11abcdef0123456789abcdef01234567 SECRET
14 ansible_vault $ANSIBLE_VAULT;1.1;AES256 SECRET
15 hashicorp_vault_token hvs.ABCDEFghijklmnop123456 SECRET
16 email user@example.com IDENTIFIER

Placeholder Formats

Secrets (counter-based, per request): Replaced with <PLACEHOLDER_N> where N increments per type within a single request.

sk-ant-api03-abcdef...  ->  <ANTHROPIC_KEY_1>
ghp_xxxxxxxxxxxx...     ->  <GITHUB_TOKEN_1>

Identifiers (HMAC-based, deterministic): Replaced with <PLACEHOLDER_HMAC:HEXHEX> using a truncated HMAC-SHA256 digest. The same input always produces the same placeholder (given the same key), enabling correlation across requests.

user@example.com  ->  <EMAIL_HMAC:A3F1B2C0>

What the Scrubber Skips

  • JSON skip-set keys: model, role, type, stop_sequences, temperature, top_p, max_tokens, top_k, stream, metadata, input_schema. Values under these keys are never scrubbed.
  • Tool definition keys: name and description are additionally skipped inside tools arrays.
  • Image data: Base64 image payloads ({"type": "base64", "data": "..."}) are left untouched.
  • Non-JSON bodies: Bodies that fail JSON parsing are passed through unchanged.
  • Oversized bodies: Bodies exceeding SCRUB_MAX_BODY_SIZE (default 10 MB) are passed through unchanged.
  • Non-POST requests: Only POST request bodies are scrubbed.

Endpoints

Endpoint Port Description
GET /health 8443 Returns {"status": "ok"}
GET /metrics 8443 JSON snapshot of request counts, error rates, bytes, tokens, scrub stats
GET /metrics/stream 8443, 9090 SSE stream of metrics snapshots (every 1.5s)
GET /dashboard 8443, 9090 Live HTML dashboard
* /{path} 8443 Catch-all reverse proxy to upstream

Dashboard

The live dashboard is a single-page HTML app served at /dashboard on both the main HTTPS port and the plain HTTP dashboard port (default 9090). It connects via SSE to /metrics/stream and displays:

  • Requests per second and output tokens per second (time-series charts, last 60 samples)
  • Error rate, active requests, uptime
  • Data throughput (bytes in/out) and token totals (input/output)
  • Status code breakdown table
  • Alert banner for high error rate (>10%) or high active requests (>10)

Deployment

An Ansible role is included under deploy/ansible/. It handles:

  1. Creating a dedicated system user (anthropic-proxy)
  2. Syncing source code to /opt/anthropic-proxy/app/
  3. Installing uv and running uv sync
  4. Deploying a .env file and systemd service unit
  5. Configuring UFW firewall rules for both ports
  6. Health-checking the service after startup
# Deploy to hosts defined in deploy/ansible/inventory.ini
make deploy

Development

Make Targets

Target Description
make install Install dependencies with uv sync
make run Run proxy locally with debug logging and self-signed TLS
make deploy Deploy via Ansible
make logs Tail remote service logs
make status Show remote systemd service status
make health Curl the /health endpoint
make metrics Curl the /metrics endpoint

Running Tests

uv run pytest

Project Structure

src/anthropic_proxy/
    __init__.py
    config.py          # Settings and validation (pydantic-settings)
    main.py            # FastAPI app, proxy logic, metrics, dashboard server
    scrubber.py        # Secret detection and pseudonymization
    dashboard_html.py  # Inline HTML/JS/CSS for the live dashboard
tests/
    test_scrubber.py
deploy/ansible/
    playbook.yml
    inventory.ini
    roles/anthropic_proxy/
        tasks/main.yml
        templates/      # .env and systemd unit templates
        defaults/main.yml
        handlers/main.yml

Architecture

  1. A client sends a request to anthropic-proxy over HTTPS.
  2. The proxy reads the request body. If scrubbing is enabled and the request is a POST, the scrubber parses the JSON body, walks the structure (skipping known-safe keys and image data), and replaces detected secrets with deterministic placeholders.
  3. The proxy forwards the request to api.anthropic.com via an HTTP/2 connection pool, streaming the response back to the client.
  4. On 529 (overloaded) responses, the proxy retries up to 3 times with exponential backoff (1s, 2s, 4s).
  5. Metrics (request counts, status codes, bytes, tokens, scrub hits) are recorded and exposed via /metrics and the SSE stream powering the dashboard.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors