Files
zooqueenandHanzo Dev 37e2719185 Run the proxy where the sites already run
The DigitalOcean account was suspended, so everything on DOKS is gone:
api.zoo.cloud, api.zoo.network, gym.zoo.ngo and iam/kms.hanzo.ai all answer
525 — Cloudflare reaching for an origin that is not there — and zoolabs.id
and zoo.id do not resolve at all. apps/api is a Fastify process that wants a
cluster, so it has nowhere to go and Blue stays unreachable.

The sites themselves never noticed, because Pages serves them from
Cloudflare's own edge. So this does the same job from the same place: hold
the tenant credential, allow only our origins, meter what one caller spends,
stream the reply through. No origin, nothing to keep alive, and it sits
beside the sites it serves rather than in a cluster they do not depend on.

Two things it does better than the process it stands in for. The rate limit
is Cloudflare's, counted across the whole edge rather than per replica — the
ceiling apps/api could only approximate and said so. And the upstream is a
binding rather than a constant, so the tests point it at a real server and
check what actually crosses the wire.

Seven tests, all against a live upstream: preflight allowed for our sites,
refused for a stranger — including zoolabs.io.evil.test, which passes a
prefix check and must not pass this one — the tenant key added upstream and
never asked of the browser, a reply arriving as a stream rather than a lump,
and a missing credential answering 503 rather than pretending.

Deploying needs `wrangler secret put HANZO_API_KEY` and `wrangler deploy`.
api.hanzo.ai is still up, so the moment that lands, chat works on both sites
with no change to either.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-02 16:58:13 -07:00

Symbolic link
6 B