Core Concepts

The AI Gateway (Team Mode)

Run LeanCTX as a shared org gateway: one deployment your whole team points its IDEs at, with per-person keys, usage metering, an org model catalog, policy gates and signed, verifiable savings evidence. Compiled into the default binary — nothing changes for solo use until you run it.

Everything else in these docs runs on your machine. The AI Gateway is the same engine running for your whole team: one shared deployment that every IDE, CLI agent and script points at, instead of each laptop talking to the model providers directly. Requests are compressed on the wire, attributed per person, metered to Postgres, governed by org policy — and the savings are recorded in a form you can hand to finance.

It is compiled into the default binary (the gateway-server feature) and shipped since v3.9.0. The local-free invariant holds: until you run lean-ctx gateway serve, nothing about solo use changes.

Local proxy vs. team gateway

The local wire proxy and the gateway are the same wire path at two scales. The proxy binds to 127.0.0.1, serves one person, and forwards that person's own provider key. The gateway binds a real interface, serves an org, and changes the trust model accordingly:

Local proxyTeam gateway
Bind127.0.0.1 onlyproxy_bind_host (e.g. 0.0.0.0), Host-header allowlist via proxy_allowed_hosts
Who calls ityour own AI toolsevery seat in the org
Authlocal token / provider-key fallbackmandatory per-person Bearer keys — the fallback is hard-disabled on any non-loopback bind
Upstream credentialsforwards your key verbatiminjects org keys from env (api_key_env) — provider keys never live on laptops
Meteringlocal ledgerPostgres usage_events, per person / team / project / model
Governancesigned org policy: model ceiling, budgets, rate limits
Rate limitunlimited50 rps floor (burst 100) by default, tunable via proxy_max_rps

Serve, init, doctor

gateway serve starts the multi-provider reverse proxy — Anthropic, OpenAI, Gemini, Ollama and any custom registry provider — plus a token-protected admin console on a separate port. gateway init scaffolds a ready-to-run deployment: docker compose file, .env, per-person key file and a step-by-step README in one command. gateway doctor preflights config, secrets, database and ports before go-live.

lean-ctx gateway init acme-gateway --org="Acme" --seats=800 \
    --reference-model=claude-sonnet-4-5 --person=alice@acme.com --person=bob@acme.com
cd acme-gateway && docker compose up -d
lean-ctx gateway doctor          # go-live preflight: config, secrets, DB, ports
lean-ctx gateway serve           # or run the binary directly (port 8484, admin 8485)

The admin console and /metrics (Prometheus) listen on the admin port, loopback by default — exposing them is an explicit decision ([gateway_server] admin_bind_host). The admin Bearer token comes from LEAN_CTX_GATEWAY_ADMIN_TOKEN, the metering DSN from DATABASE_URL; neither ever lives in the config file.

Per-person keys — hashed, rotatable

Every seat authenticates with an individual Bearer key. The gateway stores SHA-256 hashes only — plaintext is shown exactly once at creation. rotate replaces all of a person's keys in one atomic file swap, so there is no window where the person has zero valid keys, and team/project attribution survives the swap.

lean-ctx gateway keys add --person=alice@acme.com --team=platform --project=checkout
lean-ctx gateway keys list
lean-ctx gateway keys rotate --person=alice@acme.com   # atomic, attribution kept
lean-ctx gateway keys revoke --person=alice@acme.com

The org model catalog — /v1/models and routing aliases

[proxy.routing.aliases] defines the org's model namespace: stable names like acme/fast that resolve to a concrete provider:model target. Clients discover them via GET /v1/models — content-negotiated, so OpenAI-shape and Anthropic-shape clients each get their native list format. The gateway resolves the alias, injects the upstream credential and stamps routed_from into the ledger. A model swap for 800 seats is one config line, not a laptop rollout.

[proxy.routing]
enabled = true

[proxy.routing.aliases]
"acme/fast"     = "foundry:gpt-4o-mini"
"acme/standard" = "anthropic:claude-sonnet-4-5"
"acme/premium"  = "anthropic:claude-opus-4-6"

Routing is fail-open by construction: any lookup or classification miss routes nothing and forwards the request unchanged. Custom upstreams — Azure AI Foundry, OpenRouter, self-hosted vLLM/Ollama — join as [[proxy.providers]] entries served under /providers/<id>/…, and wire-shape translation means an Anthropic-speaking IDE can call an OpenAI-hosted model and vice versa.

Personal usage view — /me

Each person signs in to /me with their own gateway key and sees exactly their spend, savings, trend, models and projects — never anyone else's. Dark/light, 24h–90d windows, savings-share KPI. The org-wide view lives on the admin console; the split keeps individual usage private by default.

Policy gates — ceiling, budgets, rate limit

Under a signed, pinned, enforced = true org policy the forward path refuses: models outside the [routing].allowed_models ceiling (403), spend above [budgets] caps per person/UTC-day or project/UTC-month (429), and requests beyond [budgets].max_requests_per_minute_per_person (429 with an honest Retry-After). Errors arrive in the caller's wire shape; refusals are counted on leanctx_policy_blocked_total{reason="model_ceiling"|"budget"|"rate_limit"}. Without an enforced org policy every gate is a no-op — governance is opt-in, not ambient.

Verifiable savings — report, evidence, baseline

Metering records both what each request cost and what it would have cost uncompressed against a contractually frozen [proxy.baseline] reference_model. Local inference (Ollama/vLLM) is booked at a transparent shadow rate instead of zero, so savings stay honest. gateway report renders the org's numbers as HTML; gateway evidence exports Ed25519-signed daily aggregates that anyone can verify offline — the foundation for savings-based pricing.

lean-ctx gateway report --out=lean-ctx-report.html          # last 30 days
lean-ctx gateway evidence --out=leanctx-evidence.json        # signed export
lean-ctx gateway evidence verify --file=leanctx-evidence.json

Retention & GDPR

[gateway_server] usage_retention_days bounds how long usage_events rows live; pseudonymize_persons replaces person identifiers with a stable keyed pseudonym before they reach metering, budgets, dashboards and logs. Person-scoped export and erasure work either way:

lean-ctx gateway gdpr export --person=alice@acme.com --out=alice.json
lean-ctx gateway gdpr delete --person=alice@acme.com --yes

Fail-open by design

The gateway never trades availability for bookkeeping: if Postgres is briefly unavailable, traffic keeps flowing and metering degrades — a request is never refused because a database was down. Only enforced policy gates refuse requests, and they answer in the caller's wire shape with actionable status codes.

Where to go next