Façades in. One model through.
Most AI gateways are HTTP reverse proxies that grew a model list: the request shape is the abstraction, so every new modality or lifecycle becomes a special case somewhere else. Wäg starts from the inference request as a domain object and treats OpenAI, Anthropic and Gemini API shapes as façades that map into it.
Six things that are first-class, not inferred
In an HTTP-shaped gateway these are derived from a path, a header or a provider SDK's behaviour. Here they are fields on a domain object, which is why policy, routing, caching and accounting can reason about them uniformly.
That one decision is why chat, embeddings, vision, audio, async video jobs and realtime sessions share a single policy, routing and accounting path instead of six.
Speak the dialect, keep the fidelity
Clients send OpenAI, Anthropic or Gemini-shaped requests, or the native inference-request shape directly. Native adapters preserve provider-specific behaviour — tool calling, vision, structured output — rather than flattening everything through one lowest-common-denominator shape and losing capability at the edges.
Nine stages, in a fixed order
Every request moves through the same stages. Identity, model access and budget resolve before anything is called; input policy runs before the cache, so even a cached answer is screened; routing picks the deployment; output and tool policy run on the answer; cost, verdicts and evidence land on the way out.
- 01Authenticate
Virtual key, agent token, or a corporate IdP token on /v1 (Enterprise). Resolves org, team, user, application and agent run.
✗ 401 - 02Model access
Model grants, narrowed by the key's allow-list, decide which aliases this identity may call.
✗ 403 - 03Budget
Rate limits and budgets are reserved on key, org, team, user, application and model. All of them must pass.
✗ 429 — no provider spend - 04Policy (pre-call)
Ordered guardrail chain on the input: PII, injection, moderation, or your own webhook. A masked prompt is what the cache sees.
✗ BLOCK · ◑ MASK · ◐ REDACT - 05Cache
Exact → canonical → near-dup → semantic, each tier gated against false hits. A hit skips the provider and the output stages.
✓ HIT — return, no provider call - 06Route
Capability filter, residency, session affinity, then the routing strategy picks the deployment. A failover never leaves the allowed jurisdictions.
- 07Invoke
Provider dialect, true SSE streaming, same-alias failover, then ordered fallbacks; each attempt writes a ledger egress entry. Mid-stream policy runs on a rolling window.
- 08Policy (post-call)
Output guardrails run on the full answer. Tool calls the model hands back are judged by tool policy: allowed, removed with a note, or refused.
✗ 403 · removed - 09Account
Budgets settle, the ledger records the outcome, and tokens, cost, verdicts and the routing decision land as request logs, OTEL traces and Prometheus metrics.
A proxy forwards a request. This decides what the request is allowed to be — which is the whole distinction between a gateway and a control plane.
Four lifecycles, one policy path
Because lifecycle is a field on the request rather than an implementation detail of an endpoint, the same governance applies to all four.
Sync
Request in, completion out, all policy applied inline.
Streaming
True server-sent events via LiveStream adapters — no full upstream buffer on the happy path. Mid-stream policy can abort a bad stream before it reaches the client.
Async jobs
Durable leased workers for long work like video and batches: enqueue → claim → heartbeat → complete, with a reaper for expired leases. Crash-safe.
Realtime
A WebSocket bridge, so live voice and streaming interactions share the same auth, budgets and logging as everything else.
This is the part an HTTP-shaped gateway cannot retrofit without a rewrite. Lifecycle has to be in the domain model before policy can apply to it uniformly.
Four planes, separated on purpose
| Plane | What it holds | Why it's separate |
|---|---|---|
| Data plane | The request path. Stateless Rust replicas: auth, budget checks, policy, cache, routing, invocation, accounting. | Scales horizontally and independently. No admin dependency in the hot path. |
| Control plane | Configuration, identity, policy definitions, budgets, keys, tenants, MCP registry. | Yours, not ours. No vendor tenancy exists to depend on or to compel. |
| Analytics plane | Usage, spend, traces, audit records. | Separated from control storage so reporting load never touches enforcement. |
| Policy plane | Scanner engines, OpenFGA relations, price book. | Pluggable and out-of-process, so a policy change doesn't require a gateway change. |
Kubernetes-native, not Kubernetes-compatible
Anything in a container is Kubernetes-compatible. Native means the platform models the thing you are running: Wäg ships its own operator and custom resources, so the gateway is an object the cluster understands rather than a deployment somebody wired up. A WaegInstance owns the gateway's Deployments, networking, autoscaling and monitoring, and reports a misconfiguration as a condition with a reason; providers, models, organizations, budgets, guardrails and keys can be custom resources too. Because budgets and rate limits are shared through Redis rather than held per replica, scaling out never lets a budget be spent twice — and the operator marks an instance with several API replicas and no Redis as not ready. It needs Kubernetes 1.28 or newer, or OpenShift 4; a Helm chart is there if you would rather template than operate.
Rust in the data plane
Built on tokio, hyper and axum with zero-copy streaming paths, shipped as one distroless, non-root binary. No interpreter, no package manager, no Node runtime in the gateway — the admin console is served by the same binary. There is no ML router in the hot path, so routing adds deterministic analysis rather than model inference.
Gateway throughput depends on payload shape, provider latency, cache hit rate, policy chain depth and concurrency. A single multiplier against another product tells you about the configuration someone chose, not about your workload. We would rather publish the harness so you can measure the thing you actually care about.
What Wäg is not
Stated plainly so you evaluate it on the right axis, and so nobody books a briefing expecting the wrong product.
- Not an inference server. It does not run models. It routes to the ones you already use, including self-hosted vLLM or Ollama endpoints, and Wäg Edge governs models running on members' computers and in mobile apps.
- Not a model host. No weights, no GPUs, no fine-tuning pipeline.
- Not a vector database. It proxies embeddings calls and caches semantically; it does not store your corpus.
- Not an observability backend. It emits OTEL and Prometheus into whatever you already run.
- Not an API gateway replacement. Kong and Envoy govern HTTP. Wäg governs tokens, models and agent actions. They are complementary layers, and most estates run both.
One endpoint. Every model. Complete control.
Run it in your own infrastructure
Everything you need to run a control plane in production is Apache-2.0 and stays that way — routing, HA, caching, failover, budgets, policy, MCP, jobs and observability. Self-hosted, no account, no phone-home.
$ docker run -p 4000:4000 <registry>/waeg-gateway:<version>Not a working pull: the images are not public yet. Design partners receive the registry details privately.
Deploy in 5 minutesShape it as a design partner
Wäg is not publicly released yet. We are working with a small cohort of teams running multi-provider AI in production, and serious about governance and sovereignty, to harden the control plane on real workloads.
- Every Enterprise capability included, at no licence cost
- Hands-on migration — we do it with you, including from LiteLLM
- A direct line to the engineers building it, and real influence on what ships next