Documentation
¶
Overview ¶
client.go is the ONE HTTP path from this subsystem to Hanzo Zero Trust — the OpenZiti-based fabric controller (hanzoai/zt) at zt-controller.hanzo.svc. Every handler in zt.go routes through this client, so the wire contract (base URL, the Ziti Edge Management API base path, session auth, the {data,meta} / {error} envelope, pagination, error mapping) lives once here and can never drift between hand-rolled fetches.
API. The controller exposes the OpenZiti Edge MANAGEMENT REST API under /edge/management/v1 (controller/webapis/versions.go: ManagementRestApiBaseUrlV1). It is the admin surface — listing services and edge-routers — as distinct from the per-identity Client API. We speak it as a thin net/http client rather than pulling the heavy generated openapi client, exactly as clients/visor fronts Visor.
AUTH (one rule). The controller authenticates a management caller with the password method: POST /authenticate?method=password {username,password} returns a session token, which every subsequent request carries in the `zt-session` header (controller/api/cors.go: ZitiSession = "zt-session"). The username/password are the KMS-injected service credential ZT_CLIENT_ID / ZT_CLIENT_SECRET — never hard-coded, never logged. The token is cached until its expiry and transparently re-minted (including a single retry when the controller rejects a stale token with 401), so a handler never sees auth state.
ENVELOPE. Ziti wraps a success as {data,meta} (data is the resource or list, meta.pagination drives paging) and a failure as {error:{code,message}} at a non-2xx status. call() maps a non-2xx to that error honestly (never masking an upstream failure as success) and returns the raw 2xx body for the typed decoders.
TLS. The controller fronts its own CA. ZT_CA_PEM (a PEM bundle, KMS-injected) pins the controller's root when set; otherwise the system pool is used (works when the controller is fronted by a publicly-trusted cert via hanzoai/ingress). ZT_INSECURE_SKIP_VERIFY is an explicit, documented dev-only escape hatch; the secure default is full verification.
types.go holds the ZT wire structs (what the OpenZiti Edge Management API returns) and the console view structs (what this subsystem emits), plus the PURE mapping between them. The view JSON keys mirror the console modules EXACTLY so the Networks, Service Mesh and Edge pages render with no front-end change:
- networkView -> console NetworksModule.tsx BootnodeNetwork {id,name,chain,status,nodes,rpc}
- meshView -> console ServiceMeshModule.tsx MeshService {id,service,namespace,mtls,requests,status}
- edgeNodeView -> console EdgeModule.tsx EdgeNode {id,name,region,status,requests,latency}
Every field is a REAL ZT value or an honest omission. Telemetry ZT's management API does not carry (per-service request counts, per-router latency) is left off the view so the UI renders "—", never a fabricated 0.
TENANT ISOLATION. ZT (OpenZiti) has no native org tenancy; services and edge-routers are scoped by their `roleAttributes` — the SAME first-class strings Ziti uses to drive service and edge-router policies. The org boundary is therefore the role attribute "org-<org>": a resource belongs to a tenant iff its roleAttributes contains that exact string (the org is the validated IAM owner, used verbatim). List/get filter to the caller's role, so one tenant can never see another's services or nodes. An untagged resource belongs to NO org and is invisible to every tenant — honest-empty over a cross-tenant leak.
Package zt mounts the Hanzo Cloud NETWORKING surface: the tenant's Hanzo Zero Trust footprint — overlay networks, mesh services and edge nodes — served as clean, org-scoped REST off the unified cloud binary and fronting the Hanzo Zero Trust controller (hanzoai/zt, an OpenZiti-based fabric). It exists so the console's Networks, Service Mesh and Edge pages read REAL per-org ZT state from ONE place (api.hanzo.ai/v1/*) instead of rendering "not connected".
This subsystem OWNS no ZT state — the controller does. It is a thin, tenant-scoped translator: it fronts the controller's Edge MANAGEMENT API (/edge/management/v1), filters every resource to the caller's org by the "org-<org>" role attribute, and re-shapes ZT objects into the exact JSON the console modules consume (types.go). It never fabricates: a mesh row is a real ZT edge service, an edge node is a real edge-router with its real online status, and a network exists only when the org actually has edge-routers on the fabric.
Surface (every route org-scoped by the validated principal; HIP-0026):
GET /v1/networks the org's ZT overlay network(s) -> {networks:[networkView]}
GET /v1/networks/:id one overlay network by id -> networkView (404 if absent)
GET /v1/mesh/services the org's ZT edge services -> {services:[meshView]}
GET /v1/edge/nodes the org's ZT edge-routers -> {nodes:[edgeNodeView]}
Networks maps to the fabric overview (edge-routers are the overlay's nodes), Service Mesh to ZT edge services, and Edge to ZT edge-routers — the three ZT concepts the three console pages need.
TENANT ISOLATION. The org (principal.Org, the validated IAM owner) selects the "org-<org>" role attribute; the client lists the controller's resources and this subsystem filters to that role, so a caller can only ever read their OWN tenant's ZT footprint. The org is taken from the validated identity, never a client field.
FAIL-CLOSED. Absent the ZT service credential (ZT_CLIENT_ID / ZT_CLIENT_SECRET, KMS-injected) the subsystem mounts its full route space but every op returns an honest 503; it NEVER fabricates a network, service or node.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
This section is empty.