@reinhartsamuel/clawguard
v0.1.1
Published
Transparent API proxy and firewall for AI spending — budget caps, anomaly detection, loop prevention
Readme
ClawGuard
The API firewall that kills catastrophic cloud bills before they happen.
ClawGuard is a transparent proxy that sits between your AI agents and cloud providers (OpenAI, Anthropic, Google). It intercepts every request, enforces spending caps, detects anomalies, kills runaway loops, and alerts you in real-time — without changing a single line of your application code.
Origin: A 3-person startup received an $82K bill in 48 hours from a compromised Gemini API key. Google cited "Shared Responsibility" and refused to waive it. ClawGuard exists so that never happens to you.
What it does
- Hard budget caps — hourly / daily / monthly spending limits per key and globally. Requests are blocked the moment a cap is exceeded.
- Anomaly detection — EMA baseline + z-score spike detection. Warns at 3σ, blocks at 10σ. Adapts to your normal usage pattern automatically.
- Loop detection — Content fingerprinting (djb2), heartbeat storm detection, and cost spiral detection. Stops runaway agents before they drain your account.
- Per-key policies — Set independent budgets and anomaly thresholds for each API key, in addition to global caps.
- Real-time alerts — Telegram notifications for budget warnings, anomaly spikes, loop detections, and key freezes.
- Live dashboard — React dashboard with real-time WebSocket feed, spend charts, alert timeline, and key management.
- Zero code changes — Just point
OPENAI_BASE_URLat ClawGuard. Works with any OpenAI-compatible client.
Quick start
Option 1 — Install script (no Bun required):
curl -fsSL https://raw.githubusercontent.com/Reinhartsamuel/clawguard/main/install.sh | shDownloads a pre-compiled binary for your OS/arch. No runtime dependencies.
Option 2 — From source (requires Bun ≥ 1.0):
git clone https://github.com/Reinhartsamuel/clawguard
cd clawguard && bun install
bun run packages/cli/src/index.ts initThen:
clawguard init # generate .env config (if not done above)
clawguard start # start proxy + dashboardYour proxy is now running at http://localhost:4100.
Configure your AI client to route through ClawGuard:
# OpenAI SDK / any OpenAI-compatible client
export OPENAI_BASE_URL=http://localhost:4100
# Anthropic SDK (via OpenClaw or LiteLLM adapter)
export ANTHROPIC_BASE_URL=http://localhost:4100
# Claude Code
export ANTHROPIC_BASE_URL=http://localhost:4100Your API keys stay exactly where they are — in your app's environment. ClawGuard sees them on each request, hashes them immediately, and never stores the raw key. The hash is used to track spend and apply per-key policies.
How it works
Your app → ClawGuard proxy → OpenAI / Anthropic / Google
│
├─ Hash API key (raw key never stored)
├─ Check: is key frozen?
├─ Check: budget cap exceeded?
├─ Check: loop detected?
├─ Check: anomaly spike?
│
├─ ALLOW → forward to provider, stream response
├─ WARN → forward + fire Telegram alert
└─ DENY → return 429 immediatelyProvider detection is automatic from the key prefix:
sk-ant-*→ Anthropicsk-*→ OpenAIAI*→ Google Gemini
API keys — how they work
ClawGuard never stores your raw API keys. Here's the full picture:
| Where | What lives there |
|-------|-----------------|
| Your app's env (OPENAI_API_KEY, etc.) | The raw key — ClawGuard never touches this |
| Request Authorization header | Raw key in transit — hashed on arrival, never logged |
| ClawGuard SQLite DB | Key hash only — used to track spend and policies |
| ClawGuard .env | Proxy config only (port, budget caps, Telegram token) |
When a request arrives, ClawGuard hashes the key, looks up any per-key policy by hash, and applies budget/anomaly/loop checks — all without ever persisting the raw key anywhere.
The dashboard's Register Key feature lets you pre-create a policy (with a human-readable label) for a key before it's ever used. You paste the raw key once into the registration form; the proxy hashes it server-side and discards the original. The hash is stored; the key is not.
Configuration
ClawGuard is configured entirely via environment variables (generated by clawguard init):
PORT=4100
CLAWGUARD_DB_PATH=data/clawguard.db
# Budget caps (USD) — leave blank to disable
CLAWGUARD_BUDGET_HOURLY=
CLAWGUARD_BUDGET_DAILY=10
CLAWGUARD_BUDGET_MONTHLY=100
CLAWGUARD_WARN_THRESHOLD=0.8 # Alert at 80% of cap
# Anomaly detection (standard deviations above baseline)
CLAWGUARD_ANOMALY_WARN_MULT=3 # Warn at 3σ
CLAWGUARD_ANOMALY_KILL_MULT=10 # Block at 10σ
CLAWGUARD_ANOMALY_MIN_SAMPLES=10 # Samples before detection activates
# Loop detection
CLAWGUARD_LOOP_ENABLED=true
CLAWGUARD_LOOP_DUP_THRESHOLD=5 # Same request 5× in window → block
CLAWGUARD_LOOP_DUP_WINDOW=300 # Window in seconds
CLAWGUARD_LOOP_SPIRAL_AMOUNT=2 # $2 in 5 minutes → block
CLAWGUARD_LOOP_HB_THRESHOLD=30 # 30 requests in 60s → block
# Telegram alerts
CLAWGUARD_TELEGRAM_BOT_TOKEN=
CLAWGUARD_TELEGRAM_CHAT_ID=Dashboard
The web dashboard is included and starts automatically with clawguard start:
- Overview — live spend charts, model mix, request log, alert feed
- Keys — registered keys with spend, per-key policy editor, freeze/unfreeze
- Alerts — full alert timeline with severity and type filters
Dashboard runs at http://localhost:5173 in development.
Management API
GET /health # Health check
GET /api/status # Global spend + all keys
GET /api/keys # All keys with spend and policies
POST /api/keys/register # Register a key (hash only — raw key never stored)
GET /api/keys/:hash/policy # Get per-key policy
PUT /api/keys/:hash/policy # Set/update per-key policy
DEL /api/keys/:hash/policy # Remove per-key policy
POST /api/freeze # Freeze a key
POST /api/unfreeze # Unfreeze a keyCLI
clawguard init # Generate .env config
clawguard start # Start proxy + dashboard
clawguard start --no-dashboard # Proxy only
clawguard status # Print current spend
clawguard freeze --key <hash> # Freeze a keyArchitecture
packages/
├── proxy/ # Bun + Hono proxy (the core)
│ ├── router/ # Ingress (key detection, hashing) + egress (streaming, token counting)
│ ├── policy/ # Budget caps, anomaly detection, loop detection
│ ├── store/ # SQLite (bun:sqlite): requests, counters, baselines, frozen keys
│ ├── alert/ # Telegram dispatcher
│ ├── tokens/ # Token counting + LiteLLM-backed pricing (500+ models)
│ └── ws/ # In-process pub/sub for real-time dashboard feed
├── dashboard/ # React 19 + Tailwind + Recharts
└── cli/ # clawguard CLIStorage: SQLite (WAL mode) — no external database required.
Real-time: Native WebSocket via Bun.serve — no extra dependencies.
Pricing: Live from LiteLLM's model pricing JSON, cached 24h locally, with hardcoded fallback.
Self-hosting vs managed cloud
ClawGuard is fully self-hostable — all you need is Bun and a machine. No external services required except Telegram (optional).
A managed cloud offering is in development. Join the waitlist →
Contributing
- Fork the repo
- Install dependencies:
bun install - Run tests:
bun test - Start dev server:
bun run dev
All PRs welcome. Please keep TypeScript strict (no any), no classes, and run bun test before submitting.
License
MIT — see LICENSE.
