console

package
v1.786.32 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 3, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package console mounts the console's OWN standalone server surface natively in the unified cloud binary at /v1/console/* (HIP-0106). It is the Go port of the two console2 Next server routes that hold NO backend-proxy role but DO privileged IAM work on the signed-in user's behalf — app/keys/route.ts and app/onboard/route.ts — so console2 can drop those Node server handlers and be statically exported (task #41, "True 1-binary FE": the console SPA is go:embed'd and every dynamic call terminates at THIS binary's /v1, no separate Node origin).

WHY THESE TWO (and not the rest). console2's other server routes are pure BFF reverse-proxies (app/cloud, app/ai, app/commerce, …) that forward the browser to a backend service. In the one-binary model the cloud binary IS that backend, so those proxies vanish — the SPA calls /v1/* on its own origin and the already- mounted subsystems answer. `keys` and `onboard` are different: they are NOT proxies, they run real logic (mint/revoke the user's `hk-` key; create an org + move the user in) as the confidential `hanzo-console` client. They have no cloud equivalent, so they must be ported for the static export to be complete.

SURFACE (every route requires a VALIDATED principal — a gateway-minted, IAM- verified X-User-Id; a client-forged X-Org-Id on the bearer-less path is refused):

GET    /v1/console/keys      — whether the caller has an `hk-` key (+ prefix/mtime); no secret.
POST   /v1/console/keys      — mint/rotate the key; returns { accessKey } ONCE.
DELETE /v1/console/keys      — revoke the key.
POST   /v1/console/onboard   — create the caller's org (+ move them in on first run).
GET    /v1/console/health    — real IAM-configured probe (fail-closed when unwired).

TENANCY. The caller is resolved from the VALIDATED identity headers ONLY (principal.Validated / c.Org() / c.User()), the same trust boundary every mutating subsystem uses. The IAM id targeted is DERIVED as `<owner>/<name>` from those validated claims — never taken from the request body/query — so a caller can only ever mint/revoke their OWN key and onboard THEMSELVES; there is no path to name a third-party subject. When the confidential client is unwired the surface is honestly "not configured" (501), never a fabricated key or org.

iam.go is the ONE HTTP path from the console subsystem to Hanzo IAM, acting as the confidential first-party `hanzo-console` client (client_secret_basic). It ports the privileged IAM primitives that console2's server-only src/lib/server/identity.ts drove — mint/revoke/get the per-user `hk-` key and create/read/update an organization — so those standalone Next server routes can be retired and console2 statically exported (task #41, "True 1-binary FE").

WHY A CONFIDENTIAL CLIENT (and not the caller's own token). These ops are privileged: `mint-user-keys` writes a user's AccessKey, `add-organization` creates a tenant and moves the user in. IAM authorizes them for an app that is allow-listed (IAM_KEY_MINT_ALLOWED_APPS / IAM_ORG_ADMIN_APPS / IAM_USER_ADMIN_APPS) — the `hanzo-console` client — NOT for an arbitrary user bearer. So this client authenticates as that app (Basic id:secret) and always targets the ALREADY-VALIDATED caller (the handler resolves the principal from the gateway-minted X-User-Id/X-Org-Id before calling here); the caller can only ever act on their OWN id, never a third party's.

CREDENTIALS come from server-only env (IAM_MINT_CLIENT_ID / IAM_MINT_CLIENT_SECRET, sourced from KMS by the deployment), never a NEXT_PUBLIC value and never the browser. When they are unset the subsystem is honestly "not configured" (501), exactly as identity.ts's mintConfigured() gate behaved — no fabricated key/org.

onboarding.go — PURE org-naming + reserved-name policy, no transport/IAM. A faithful Go port of console2's src/lib/server/onboarding.ts, decomplected from the handler so the naming rules are one testable thing (the route does the IAM calls; this decides the slug). Two concerns:

  • NAMING: turn a human org name (or a username) into a valid IAM org slug — lowercase, [a-z0-9-], collapsed, trimmed, bounded.
  • RESERVED: refuse names that must never become a customer org — IAM system owners (admin/built-in/app) and the brand/staff orgs (hanzo/lux/zoo/pars), which the OrgGate routes to the admin host. Creating one would collide with a staff tenant or a system principal.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Mount

func Mount(app *zip.App, deps cloud.Deps) error

Mount wires the /v1/console surface onto app per HIP-0106.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL