Clicking "Sign in" on cloud.hanzo.ai appeared to do nothing. It was not a redirect loop and nothing returned an error — every hop was HTTP 200, which is why the page "looked fine". console.hanzo.ai/ served a SECOND copy of the Hanzo Cloud marketing page, wearing the byte-identical @hanzogui/shell header. So the journey was: cloud.hanzo.ai [Sign in] -> console.hanzo.ai/ (same header, same "Sign in") console.hanzo.ai [Sign in] -> /signin (one button, nothing else) /signin [Log in with Hanzo Cloud] -> hanzo.id Three clicks, and the first landed on a page indistinguishable from the one it left. That reads as a re-render, and users stopped there. The console is the APPLICATION; the marketing face of Hanzo Cloud is cloud.hanzo.ai. Serving a third copy of it on the app host is what created the illusion. So `/` is no longer a special surface: everything except the two auth routes is `guarded`, and a definitively-anonymous visitor STARTS the authorize hop instead of being parked on an interstitial that only asks "did you mean it?". cloud.hanzo.ai [Sign in] -> hanzo.id `startReauth()` is reused rather than `signinRedirect()`, so a deep link (/models) returns to /models after login instead of dumping the user on the home. SIGN-OUT IS PRESERVED, the one hazard here. Sign-out lands on /signin, which keeps its button and never auto-authorizes -- IAM may still hold its own session, so authorizing there would sign the user straight back in and make signing out impossible. A callback failure lands on the same surface, so a broken hop cannot loop. Removes PublicLanding + landing-surface, now unreachable (-269 lines net). Tests: 258 files / 3211 assertions pass; tsc --noEmit clean. Co-authored-by: Hanzo Dev <dev@hanzo.ai>
Hanzo Cloud Console
Unified admin console for Hanzo Cloud and all Hanzo cloud products. Built on
@hanzo/gui (cross-platform UI) over the unified /v1
backend (hanzoai/cloud). Dark theme, OIDC sign-in via Hanzo IAM.
Manages: Providers · Models · Applications · Stores · Chat — with an extensible product-module registry so every cloud product can be added as a module.
Quick start
npm install
cp .env.example .env.local
# set NEXT_PUBLIC_IAM_CLIENT_ID for live sign-in; defaults point at production.
npm run dev # http://localhost:4000
Scripts
| Script | What |
|---|---|
npm run dev |
Dev server on :4000 |
npm run build |
Production build (type-checks; Gui CSS injected at runtime) |
npm run start |
Serve the production build |
npm run typecheck |
tsc --noEmit (strict) |
Configuration
All config is NEXT_PUBLIC_* (browser app, cookie auth). See .env.example.
| Var | Default | Meaning |
|---|---|---|
NEXT_PUBLIC_CLOUD_URL |
same origin, else https://api.hanzo.ai |
The ONE Hanzo API endpoint (unified /v1 backend). Never a per-service API host. |
NEXT_PUBLIC_IAM_URL |
https://iam.hanzo.ai |
Hanzo IAM OIDC authority |
NEXT_PUBLIC_IAM_APP_NAME |
hanzo-console |
IAM application (<org>-<app>) |
NEXT_PUBLIC_IAM_ORG_NAME |
hanzo |
IAM organization |
NEXT_PUBLIC_IAM_CLIENT_ID |
— | OAuth client id |
Architecture
See LLM.md for the full design (base choice, /v1 client, auth flow, the product-module registry, and the Providers surface). Endpoint reference in docs/endpoints.md.
License
MIT OR Apache-2.0 at your option — see LICENSE,
LICENSE-MIT, LICENSE-APACHE.
Copyright (c) 2026-present, Hanzo AI, Inc. Estate-wide licensing standard: HIP-0137 (hanzoai/hips).