Skip to content

Securing the gateway

costhelm’s core security property is a credential boundary: the gateway owns every provider key; callers hold none. An agent runtime built on the gateway cannot leak a key it never had — and rotating a key touches one .env, not every consumer.

The shipped defaults assume a localhost or private-network deployment: auth off, bind 0.0.0.0:8111. Before exposing the port any wider:

Terminal window
COSTHELM_API_KEYS="key-one,key-two" costhelm serve
  • Guards everything under /v1/*. /healthz and the dashboard pages stay open (the pages’ own /v1/* reads need a key — they prompt once and keep it in localStorage).
  • Send Authorization: Bearer <key> or X-API-Key: <key>. Comparison is constant-time.
  • Failure is a 401 with a structured envelope naming the fix.
  • Multiple keys are for rotation: add the new key, roll consumers, remove the old.

Generate a key however you like, e.g. python -c "import secrets; print(secrets.token_urlsafe(32))".

Terminal window
costhelm serve --host 127.0.0.1 # localhost only

For anything crossing a network boundary, put a TLS-terminating reverse proxy (Caddy, nginx, Cloudflare Tunnel) in front — API keys over plain HTTP are only acceptable on loopback.

Prompt/completion capture on spans is off by default and should stay off against any shared collector — it is the highest-PII payload the gateway handles. Enable COSTHELM_OTEL_CAPTURE_CONTENT=1 only against a localhost collector holding test data.

A leaked consumer key spends money. Ceilings per key-holder’s principal (tenant:partner-x, agent:external-bot) bound the blast radius, and POST /v1/budget with limit_usd: 0 is an immediate kill switch for one principal — no restart, nothing else affected.