Hanzo Gateway
The trust boundary in front of the API
Every request to api.hanzo.ai passes through it. It decides who the caller is: check the token against Hanzo IAM, throw away every identity header the client sent, write the canonical ones back from the verified claims, then hand the request on.
Nothing downstream has to ask who is calling
Gateway answers that once, at the edge, so every service behind it can read an org id and believe it.
The token is checked here
A JWT is validated against Hanzo IAM's JWKS before anything else reads the request. Opaque API keys aren't JWTs, so they go on to the service that issued them and it decides.
Identity headers are written, not trusted
X-User-Id, X-Org-Id, X-Roles and every X-IAM-* variant are stripped from every inbound request, then written back from the verified claims — sub, owner, roles. A curl flag can't set them.
No route map, deliberately
For api.hanzo.ai it forwards /* straight to Hanzo Cloud, which owns the /v1 mount table. A second table here would be a second thing to keep in sync, and the first one to go stale.
Rate limits per caller and overall
Token-bucket limits by client IP and across the edge as a whole, with per-endpoint overrides in config. A rejected request gets a 429 and a Retry-After, not a dropped connection.
Liveness that consults nothing
The health check answers whether the process is up and asks no backend. A probe that fails when a dependency blinks restarts a healthy process and turns one outage into two — so backends are dialed lazily and degrade per request instead.
A hop, or no hop at all
Run it as its own service in front of the API, or mount it inside the cloud binary with one call. Same checks either way — one less network hop when you don't want one.