Live infra drift (gateway redeploy): api.hanzo.ai/v1/kms is NOT proxied (404),
and the bare /health path moved (/health 404, /v1/health 200). Two fixes:
- KMS runs on its dedicated host kms.<brand> (kms.hanzo.ai, per IAM's per-brand
KMSHost). Added brand.kms + endpoints.kms (HANZO_KMS_URL override); KMS client
targets it instead of api.hanzo.ai/v1/kms. Verified live: kms.hanzo.ai/v1/kms/
orgs/hanzo/secrets → 401 (gated, live).
- doctor now probes the STABLE endpoints the tool actually depends on — IAM
/.well-known/openid-configuration + api /v1/models — not a bare /health that
varies by gateway config. Both 200.
- kms-secrets action base-url default → kms.hanzo.ai.
Release 1.0.6 (helper + @hanzo/kms + lux/zoo/zen forks).
KMS already serves the one-way secret surface (hanzoai/kms embed.go): the dev's
IAM login token goes straight to /v1/kms/orgs/{org}/secrets — KMS verifies it
against hanzo.id JWKS (authorize + canActOnOrg). No /v1/kms/oidc/login or
/v1/kms/get-secrets exchange (those were invented; they 404). One token, one way.
- lib/kms.ts: listSecrets + getSecret + pullSecrets over the real endpoints.
Respects KMS's security boundary — list returns KEYS ONLY; values are read
one-by-one (bounded concurrency), no bulk-value dump.
- commands/kms.ts: org comes from the login session (--org override); IAM token
from config.accessToken. pull/list unchanged in UX.
- actions/kms-secrets: same canonical list-then-get; token input is an
IAM-issued token KMS trusts (GitHub OIDC only if KMS trusts that issuer).
- npm-release.yml: pass org=hanzo + KMS_IAM_TOKEN.
Verified: GET /v1/kms/orgs/hanzo/secrets?env=devnet is LIVE (401, gated) on
api.hanzo.ai — endpoint exists, needs a real IAM token to list.
A developer's `hanzo login` already mints an IAM OIDC token; `kms pull --env
devnet` exchanges it for a short-lived KMS token and writes a local .env. Clean
orthogonal separation — IAM is a pure issuer (/v1/iam), KMS owns secrets/envs/
authz (/v1/kms); they compose through the token, neither imports the other. No
broker, no /api/, no compound words (oidc, not oidc-auth).
- src/lib/kms.ts: kmsLogin + kmsSecrets + pullSecrets over /v1/kms/oidc/login
and /v1/kms/secrets; tolerant of {K:V} or [{secretKey,secretValue}] shapes.
- src/commands/kms.ts + src/kms-cli.ts: `hanzo kms` and standalone `kms` bin —
one implementation, two entry points. pull/list, env devnet|testnet|mainnet|
production (default devnet), dotenv out.
- CI shares the SAME mechanism: .github/actions/kms-secrets loads secrets via a
GitHub OIDC token through /v1/kms/*; reusable .github/workflows/npm-release.yml
publishes any package with NPM_TOKEN from KMS (self-hosted runners, no
long-lived token in GitHub); release.yml ships helper + forks on tag.
- DRY: dev and CI use one /v1/kms exchange; one login, one token store.