1.0.58 published a bundle with no key from a run in which every step was green:
the KMS step logged "ingest key resolved (40 chars)" and buildx ran with
`--build-arg EVENT_INGEST_KEY=***`. The image config it produced reads
`VITE_EVENT_INGEST_KEY=` — empty. 1.0.57, built before this file changed, reads
`VITE_EVENT_INGEST_KEY=pk-live-…`.
A second `ARG VITE_EVENT_INGEST_KEY=` had been added below the pair that sets it.
A build arg declared after an ENV of the same name shadows it for every later
expansion, so `ENV VITE_EVENT_INGEST_KEY=$VITE_EVENT_INGEST_KEY` read the empty
ARG default and overwrote the key. One name, declared twice, and the second
declaration won.
So: one declaration. EVENT_INGEST_KEY is the name in KMS and on the --build-arg;
the VITE_ prefix is applied once, here, because the prefix is a property of this
build and not of the secret.
Two gates, because nothing between the secret store and the browser had noticed:
- The Dockerfile now asserts the key it was given is actually present in
client/dist. `pnpm run frontend` is what inlines it, so that is the first
moment the question can be answered and the last moment it is cheap. An
absent key is only warned about — this image is also built without the
credential — but a key that was supplied and did not reach the artifact
fails the build. The value is never echoed.
- deploy.yml's KMS step now fails the build, with a reason. Its `exit 0`
guards had never run: the runner invokes `run:` under `bash -e`, so the
first curl returning >= 400 aborted the step first. That is how run 7 — the
commit that added the key — died as a bare `exitcode '22'` and left main
looking fixed with no image to show for it. Each curl is now rescued so the
guard decides, and each guard names which call failed.
hanzo.yml stops claiming to be what builds this repo. `.hanzo/workflows/deploy.yml`
is, run by the forge on the git-runner fleet; the `images:` block is read by
cloud's build_on_push, which these repos do not route through — no
`sha-<sha7>-amd64-chat` tag exists for any commit here. It is left as a
declaration of intent, with the warning that its enqueue body carries no
build-arg field and so cannot pass this credential at all.
Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Hanzo Chat
The chat surface of the Hanzo AI cloud: multi-model chat with agents, tools, and retrieval, running on Hanzo's backend. Live at hanzo.chat.
Hanzo Chat is a sibling to hanzo.app (the app builder) and the Hanzo console (admin). All inference, code execution, and web search route through the unified Hanzo API at api.hanzo.ai/v1, and sign-in is federated to Hanzo IAM (hanzo.id).
Features
- Multi-model chat — the Zen model family and other frontier models, served through
api.hanzo.ai. - Agents — build agents in the thread, or run your Hanzo Cloud agents (
/v1/agents) with an/agentcommand or@mention. - MCP tools — connect Model Context Protocol servers for tool use.
- RAG — chat over your own files and documents.
- Web search — grounded answers via Hanzo web search.
- Code interpreter — run code in a sandboxed runtime.
- Image generation — generate images inline.
- Guest chat — try a free Zen model with no account (optional, off by default).
Requirements
- Node.js 24 (see
.nvmrc) - pnpm 10
- A Hanzo API key — get one at hanzo.ai/dashboard
Quick start (Docker)
git clone https://github.com/hanzoai/chat.git
cd chat
cp .env.example .env # set HANZO_API_KEY
make up
Open http://localhost:3080. make up starts the full stack (app, MongoDB, Meilisearch) from compose.yml; make down stops it.
Development
pnpm install # install workspace dependencies
pnpm build:packages # build the shared workspace packages
pnpm backend:dev # API server on :3080 (nodemon)
pnpm frontend:dev # Vite client dev server (second terminal)
Tests and checks:
pnpm test:all # all workspace tests
pnpm e2e # Playwright end-to-end tests
pnpm lint # ESLint
pnpm format # Prettier
Configuration
Secrets live in .env; the model catalog and endpoints live in chat.yaml (copy chat.example.yaml). Key variables:
HANZO_API_KEY= # Hanzo API key — inference, tools, search
MONGO_URI= # MongoDB connection — chat history, users
JWT_SECRET= # session token signing
CREDS_KEY= # credential encryption
CREDS_IV=
Sign-in is federated to Hanzo IAM over OpenID Connect (OPENID_ISSUER=https://hanzo.id, client hanzo-chat).
Workspace
api/ Express backend (:3080) — routes, controllers, Mongoose models
client/ React frontend (Vite)
packages/ data-provider · data-schemas · api · client · agents · mcp
Documentation
- Docs: https://hanzo.ai/docs/chat
- Deployment, IAM, and platform notes:
docs/ - Issues: https://github.com/hanzoai/chat/issues
License
MIT. MIT licensed. See LICENSE for the full attribution.