Commit Graph
77 Commits
Author SHA1 Message Date
zeekayandHanzo Dev 71b20b983c Merge the forge line into main — one history, two remotes
Work landed on GitHub while CI reads the forge, so each side carried commits the
other did not: the forge had the module-proxy fetch, the recorded go.sum and the
sdk/go minio removal; GitHub had kms building its own zip.App. A force-push
either way would have dropped one of them silently.

go.mod conflicted only on version skew — zap v1.2.7/zapdb v1.10.0 against
v1.2.6/v1.10.6 — resolved to the higher of each, which is what version selection
picks anyway. go.sum was reconciled by re-tidying rather than by choosing a side.
Before that, every module@version the two go.sum files shared (339 in the root,
275 in sdk/go) was checked for hash disagreement: none, so no re-tag hid here.

go build ./... clean, go test ./... green.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-12 20:29:14 -07:00
zeekay c0ebcb714c kms: fetch the module graph through the proxy, not straight from git
github.com/hanzoai/cloud lost the v0.x tags it was published under — GitHub
carries v1.801.31 and nothing else — so GOPRIVATE, which implies GONOPROXY,
sent go mod download to a revision that is no longer there and build-amd64
died on "unknown revision v0.1.1". The proxy still holds it, and holds the
same bytes: the zip hashes to the h1: already in go.sum.

Dockerfile.kms-fetch never had the problem because its env assignments bind
to the git config they precede rather than to go mod download, so its graph
has always come through the proxy. Deleted there too, so both files read the
way they behave.
2026-08-12 20:08:21 -07:00
zooqueen 68fea39969 go.sum: record the modules the build already uses
Every package failed to set up, so no test ran:

  FAIL	github.com/hanzoai/kms [setup failed]
  luxfi/[email protected]/blackhole.go:6:8: missing go.sum entry for module
  providing package github.com/luxfi/…

Three indirect dependencies had moved under their own patch ranges —
container, geth and vm — and go.sum still held the older hashes. `go mod tidy`
records what the build resolves to.

Verified: go build ./... clean, go test ./... passes.
2026-08-11 17:09:20 -07:00
zooqueen 4323e1e762 sdk/go: unblock it, then take it to zero minio
This module could not build at all. luxfi/[email protected] was re-tagged after
publication, so its bytes and its recorded hash disagree permanently:

    verifying github.com/luxfi/[email protected]/go.mod: checksum mismatch
    SECURITY ERROR

and that is unrecoverable in place — the proxy and checksum database are
append-only. It also blocks its own escape: `go get luxfi/[email protected]` has to load
the current module graph first, which means verifying v1.3.1, which is the thing
that fails. So the upgrade is done by editing the requirement directly and
dropping the abandoned version's two go.sum lines. That is not accepting the
re-tag; it is leaving the version behind. Nothing here now references v1.3.1.

With the module able to resolve again, zapdb, database, geth and container come
up to the releases where each stopped pulling minio through hanzos3/go-sdk,
whose `replace` redirect Go ignores outside a main module. go.mod names zero
minio modules.

This matters beyond the tree: sdk/go is published as
github.com/hanzoai/kms/sdk/go and external consumers resolve it directly, so the
root module going clean earlier did nothing for them while this one was stuck.

build and vet pass — the first time this module has compiled in a cold cache.
2026-08-10 22:31:02 -07:00
zooqueen 2ba926f24c zero minio in the root module: zapdb v1.10.6
Nothing here ever imported minio — zero .go files reference it. It arrived
through luxfi/[email protected].0, which required hanzos3/go-sdk, which pointed at our
checksum forks with `replace`. Go ignores `replace` in a non-main module, so that
redirect reached none of zapdb's consumers and minio-go, crc64nvme and md5-simd
resolved for real. zapdb v1.10.6 requires hanzos3/go by name, which does travel.

sdk/go is NOT fixed here and could not be. It is a separate module and its build
is already broken on an unrelated supply-chain problem:

    verifying github.com/luxfi/[email protected]: checksum mismatch
      downloaded: h1:U2Bv7IDRFv8JtjUARfY53ZnOPRB2iPrPHSMDCQ+T0Js=
      go.sum:     h1:rLCbygaajehVkUoJ5czwhpUAJaC5J5okq3p+j2QSPSo=

That tag was re-pointed after publication, so its recorded hash and its bytes no
longer agree and `go get` cannot run in that module at all. Verified identical on
an untouched worktree of this same commit before concluding it. Leaving sdk/go
alone rather than reaching for GONOSUMDB or hand-editing go.sum — either would
paper over a re-tag, which is the one failure mode that must stay loud.

So: root module clean, submodule blocked behind luxfi/vm. Its published
sdk/[email protected] still carries minio for external consumers until that is resolved.
2026-08-10 21:42:59 -07:00
zeekayandHanzo Dev 4cbdfe4a9b kms is an app, so it builds its own zip.App instead of taking cloud's Deps
The coupling was one string. Mount(app, deps) took hanzoai/cloud's Deps and
read exactly two fields out of it: a logger, which luxfi/log already publishes
as a process default and which Embed has always used, and a data root.
Everything else in that struct crossed the boundary to be discarded. An init()
then pushed this package into cloud's registry so cloud could call Mount back.

That points the dependency the wrong way. It makes the graph circular, since
cloud imports kms in order to mount it, and it fixes the set of possible hosts
at one: two editions of hanzoai/cloud declare the same module path, so
cloud.Deps names a different type in each, and a package that takes it can be
composed by one of them and never the other.

kms.App(root) now builds the app and returns it, and a host composes it with
app.Use. Routes are absolute, so composition neither moves nor shadows them;
the bridge test runs through a host app with middleware in front of it to hold
that. Teardown travels with the app rather than with the process: the Embedded
server drains on a shutdown hook, and zip makes a parent drain the children it
composed, so kms.Shutdown and the package global it read are gone. The readyz
branch that answered 503 when that global was nil went with them, since a
failed Embed returns an error and no app at all.

The daemon read the host's config too, and that was a live bug: it bound
$CLOUD_LISTEN, default :8080, while its own image sets KMS_LISTEN=:8443 and its
HEALTHCHECK curls 8443. It now reads its own, through the one function that
resolves that address for both the daemon and Embed.

zip moves from v1.10.0 to v1.27.2, the version the host already selects,
because Use taking a Component is what makes an app composable at all.
middleware.Logger and the KMS_LOG_LEVEL=debug opt-in around it go with the
bump; zip logs every request itself now, so that report is no longer something
a binary can be missing.

Dropping cloud drops what it dragged in. goja, esbuild and a sourcemap parser
leave the graph: a secret store no longer links a JavaScript engine.

Both go.sum files carried a pre-retag hash for luxfi/vm v1.3.1 that no longer
matches the bits the proxy serves, which failed every build outside the
workspace. Corrected against the checksum database, which agrees with the
download.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-10 12:47:40 -07:00
zooqueenandHanzo Dev b3428751e3 reconcile the two mains: the forge carried CI and deps, GitHub carried the notice
These diverged on 2026-07-27 and never came back. The two sides touched
disjoint files, which is why neither noticed: the forge took six commits to
.hanzo/workflows/release.yml, go.mod and go.sum (dropping endpoints and cache
backends this forge does not implement), and GitHub took one to README.md
saying the repo is archived and superseded.

Merged rather than picking a winner. Nothing conflicts, and both statements are
true — the CI had to be made to work on the forge, and the repo is superseded.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-08 19:52:53 -07:00
zeekayandHanzo Dev d4087f00e3 ci: drop generate_release_notes — the forge does not implement that endpoint
Every build job passed and only the release job failed, with:

    ::error::404 page not found

`generate_release_notes: true` makes softprops/action-gh-release call

    POST <api>/repos/<owner>/<repo>/releases/generate-notes

which is a GitHub-only API. Measured against this forge:

    GET  /v1/repos/luxfi/consensus/releases                -> 200
    POST /v1/repos/luxfi/consensus/releases/generate-notes -> 404  "404 page not found"

The body is Go`s bare 404 text, which the action surfaces verbatim -- so the
error names no endpoint and reads as a broken release step or a bad token. The
base path was never wrong: the forge serves its API at /v1 and v1.26.29 already
advertises that (services/actions/context.go builds api_url as AppURL + "v1").

Releases still publish; only the auto-generated notes are gone, which the forge
cannot produce anyway.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-01 19:18:58 -07:00
zeekayandHanzo Dev f88cf1235a ci: registry cache — the gha backend cannot work on this forge
type=gha resolves its backend from an Actions runtime token that git.hanzo.ai
does not issue in a form buildx can parse, and the exporter is configured as
part of the solve -- so it fails the build rather than degrading to an uncached
one. Same defect fixed in hanzoai/o11y. ignore-error keeps a cold cache from
404ing the first build.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-01 18:13:24 -07:00
zeekayandHanzo Dev 8d4ec337a9 ci: ghcr login uses the credential hanzoai provisions
The docker job runs on hanzo-build-linux-amd64, so `secrets.GITHUB_TOKEN` is a
git.hanzo.ai token presented to ghcr.io, which has never seen it:

    Error response from daemon: Get "https://ghcr.io/v2/": denied: denied

That pair is GitHub`s own idiom and correct there; it is simply not a credential
on a self-hosted pool. orgs/hanzoai provisions GHCR_USER + GHCR_TOKEN.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-01 18:13:24 -07:00
zeekayandHanzo Dev d7484e8d06 deps: exclude versions that no longer exist upstream
The module graph could not be loaded at all: transitive requirements name
versions whose tags were wiped or whose pseudo-versions point at commits that
history rewrites removed, so `go list -m all` fails with "unknown revision" or
"invalid pseudo-version". Builds still passed because those modules supply no
package that gets compiled — the breakage is graph-level, which is exactly the
kind that only shows up on a clean checkout.

`exclude` is the mechanism for "this version is unusable": MVS then selects the
next higher one instead of trying to fetch a revision that is gone. Bumping the
requirement alone does not work, because Go still reads the excluded version
go.mod while building the graph.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-01 18:13:24 -07:00
zeekayandHanzo Dev 866c76d8ff deps: drop the stale luxfi/vm v1.3.1 go.sum lines
Both the zip and the go.mod hash recorded here were captured from a direct VCS
fetch made while GOPRIVATE covered github.com/luxfi/*, which switches off the
proxy and checksum verification together. The tag moved afterwards, so what we
wrote down no longer matches sum.golang.org.

proxy.golang.org still serves the originally-published bytes and they verify
against the log, so dropping the two lines and re-tidying restores the build
with no version change.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-01 18:13:23 -07:00
zeekay 129f058375 docs(readme): say at the top that this is archived and superseded
The description already said so; the README still opened by describing a live
product. A reader landing here now sees where it went before anything else.
2026-08-01 13:51:00 -07:00
zeekayandHanzo Dev 4eca56f961 ci: upload-artifact v3 — v4+ is refused by the forge
This workflow runs on git.hanzo.ai, which presents as GHES, and the v4 action
refuses before doing any work:

    GHESNotSupportedError: @actions/artifact v2.0.0+, upload-artifact@v4+ and
    download-artifact@v4+ are not currently supported on GHES.

v4 moved to an artifact API the forge does not implement, so this is a hard
refusal rather than a transient upload error — retrying could never help. The
damaging part is how it presents: the build step passes, the artifact step
fails, and the job reports "failed", so a green build reads as a broken one and
the artifact is silently never produced.

Found on hanzoai/chains, where every VM in a 15-way matrix compiled and then
discarded its binary at this step. Swept the estate for the same pattern.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-31 20:37:53 -07:00
zeekayandHanzo Dev 5d35f25c5e fix: complete the TypeScript 7 tsconfig migration
The first pass left three classes of config that BOTH tsc 5.9 and tsc 7
reject. Each was proven against both compilers before changing:

  TS5090  A `paths` target must be relative once `baseUrl` is gone. The
          first pass skipped the "./" prefix wherever baseUrl pointed at
          the config's own directory, reasoning it was semantically
          equivalent. It is not — without baseUrl a non-relative target
          is rejected outright, by 5.9 as well as 7.

  TS5110  `moduleResolution: node16` requires `module: node16`. The first
          pass mapped commonjs projects to node16 resolution alone, which
          BROKE those configs for the current toolchain. Both are now set.

  TS5102  `downlevelIteration` is also removed in TS7; it was missing from
          the dead-flag list.

Verified: repos that tsc 7 previously refused (base-studio, js-sdk, kv-js)
now report zero config errors on tsc 7 AND tsc 5.9.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 17:41:19 -07:00
zeekayandHanzo Dev c067bc1bfb chore(go): bump go directive to 1.26.5
Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 16:18:10 -07:00
zeekayandHanzo Dev 762ba4f33a build: migrate tsconfig to TypeScript 7 (native compiler)
TypeScript 7 is the native Go compiler and removes `baseUrl` and
`moduleResolution: node|node10`. Both appear here, so `tsc` from TS7
refuses the config outright (TS5102 / TS5108) and cannot typecheck.

`paths` targets resolve relative to `baseUrl` when it is set and relative
to the tsconfig file otherwise. Every `baseUrl` folded here already
pointed at the config's own directory, so dropping it moves nothing and
the targets are left byte-identical. Where a baseUrl pointed elsewhere,
each affected target was rewritten as join(baseUrl, target).

`moduleResolution` was chosen from the declared `module`: commonjs ->
node16, esnext/preserve -> bundler. Configs whose `module` is unset or
exotic were left alone rather than guessed at.

The result is accepted by BOTH toolchains, so nothing has to upgrade
TypeScript in lockstep. Verified on hanzo/chat packages/api: tsc 5.9
779 -> 778 errors (no regression), and tsc 7.0.2 now runs the project
in 2s where it previously refused the config.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 14:18:20 -07:00
zeekay b1f772e36d ci: drop the Gitea mirror-sync nudge
Superseded: the Hanzo GitHub App pushes a webhook, so the forge tracks GitHub
without a per-repo workflow. This file called git.hanzo.ai/api/v1/.../mirror-sync
— a Gitea API for a system we no longer drive — and would sit inert in every repo.

One mechanism, in one place, instead of ~350 copies of a cron.
2026-07-27 10:36:04 -07:00
zeekayandHanzo Dev 20ede2c6bb build(deps): zip v1.10.0 + http v0.3.0; cover the AdaptNetHTTP mount bridge
http v0.3.0 replaces the JSON header map in the ZAP frame with
length-prefixed name/value pairs ([u32 count] then [u32 nameLen][name]
[u32 valueLen][value]), taking decode to 0 allocs/op. That is a wire
break — a v0.2.x peer cannot talk to a v0.3.0 peer — so every Hanzo
module moves together. Deployment is operator-managed GitOps, so
merging aligns the code without shipping anything.

No source change was needed: mount.go already fronts the net/http
subtree with app.All("/v1/kms/*", zip.AdaptNetHTTP(h)) rather than the
removed App.Mount(prefix, http.Handler), and this module builds no ZAP
transport of its own.

That bridge was the one path the frame change touches and the one path
no test covered — every other suite calls the handler directly, in
process, so a framing regression would have landed silently.
TestMountBridge_NetHTTPOverZIP now serves the mount.go route shape over
a real TCP listener and drives it with a real net/http client, asserting
method, path, query, request headers, body, status, response headers
and repeated response headers all survive the round trip. Verified live
by mutation: drop the request header at the client and the test fails
with `request hdr = "" ... did not survive the bridge`.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 10:12:09 -07:00
zeekayandHanzo Dev 07e2adb8db build(deps): zip v1.9.0 + http v0.2.2; net/http subtree via AdaptNetHTTP
zip v1.9.0 repurposes App.Mount(prefix, addr) as prefix -> remote-address
proxying (unix/tcp ZAP), so it no longer takes an http.Handler. The
in-process KMS surface goes on the documented net/http bridge instead:
a wildcard route carrying zip.AdaptNetHTTP — byte-identical to what the
old Mount expanded to (All(prefix+"/*")), so /healthz and /v1/kms/* keep
resolving exactly as before, bare prefix included (fiber marks a trailing
greedy wildcard optional).

Also pulls zap-proto/fiber/v3 v3.2.1 in place of gofiber/fiber/v3 v3.2.0
as zip's router, transitively.

go build + go test green across every package this module owns
(github.com/hanzoai/kms, cmd/{kms,kms-fetch,kmsd,smoke-zap}) and the
sdk/go module.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 09:37:31 -07:00
zeekayandHanzo Dev cd15134667 test: put back the process-global state Embed changes, and measure only our goroutines
Four failures, both causes the same shape: state that belongs to the whole
process being read or written as if it belonged to one test.

TestEnvRequired_* (x3) failed with 401 on requests whose tokens were fine.
Embed applies ExpectedIssuer/ExpectedAudience/JWKSURL to the process-global
authConfig — that is what Embed is FOR — and stopping the instance does not put
it back. So after TestEmbed the process no longer accepted sharedIssuer, and
verification reached for a JWKS server TestEmbed had already closed. Every later
test minting a shared-issuer token got 401, and the only reason it was those
three is that they sort after TestEmbed. They passed in isolation, which is
what made it look like their problem.

jwtTestEnv.cleanup already restores exactly this; the embedded path had been
missed. Registered before jwks.Close so it runs last (t.Cleanup is LIFO).

TestConnMemory measured runtime.NumGoroutine() — process-wide — and divided it
by the connections under test. Run alone that ratio is 1.00; run inside the
package it also counts badger compactors, httptest servers and whatever else is
still up, and it read 1.15 against a [0.95, 1.05] band. The test was failing for
goroutines it does not own. It now takes a goroutine baseline and reports the
delta, which is what the heap half of the same function has always done two
lines above.

Package green, twice.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 08:53:08 -07:00
zeekayandHanzo Dev fcd565d375 ci: run every lane on the forge, leave sync.yml on the mirror
git.hanzo.ai is canonical and reads .hanzo/workflows, so build.yml,
build-kms-fetch.yml and pr-preview.yml move there by changing directory and
nothing else — same GitHub Actions syntax, same runs-on, byte-identical files.

Three more lanes had been deleted from .github/workflows without a replacement
anywhere, which silently removed this repo's only gate and the only producer of
its release binaries and semver image tags. There was no red run to show it,
because a workflow that does not exist cannot fail. Restored byte-for-byte from
history at the path the forge reads:

  ci.yml                    go test -race ./... + builds kmsd and kms
  release.yml               v* tags: 4-way binary matrix, release, multi-arch image
  check-fe-ts-and-lint.yml  frontend typecheck on PRs

release.yml's notify-universe job is left exactly as it was; it is already
continue-on-error, so a missing UNIVERSE_DISPATCH_TOKEN on the forge degrades to
a yellow job instead of failing the release.

Not restored: validate-pr-title.yml, a conventional-commit title gate inherited
with an upstream PR template. Dropped: workflow-sanity.yml, which triggers on
paths .github/workflows/** and so can never fire again once the lanes live under
.hanzo. Neither builds, tests or publishes anything.

sync.yml is replaced with the canonical copy — the variant here predated it and
had drifted.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 08:42:36 -07:00
zeekay a5faad7752 ci: nudge git.hanzo.ai to pull on push
git.hanzo.ai mirrors this repo by PULL on a ~10-minute interval, and arcd runs
CI/CD there — so every push waited out that interval before anything built.
This asks Gitea to pull HEAD immediately.

Latency only: the repo already mirrors via the App webhook, so a missing
HANZO_GIT_TOKEN or a failed curl is non-fatal and never fails the push.
Idempotent (mirror-sync just pulls HEAD) and concurrency-coalesced.
2026-07-27 08:22:11 -07:00
zeekay 6c98d29d27 ci: remove GitHub CI — native git.hanzo.ai + cd.hanzo.ai only
This workflow ran on a self-hosted actions-runner-controller pool. ARC is
decommissioned: CI executes inside git.hanzo.ai (Gitea Actions, .hanzo/workflows)
and delivery is cd.hanzo.ai reconciling the reviewed image pin in
hanzoai/universe. GitHub is a mirror and runs nothing.

Removed rather than repointed — there is no GitHub-side pool to move to, and
leaving it would keep ARC load-bearing.
2026-07-27 08:16:33 -07:00
zeekay 6c5e63ceb7 ci: remove GitHub CI — native git.hanzo.ai + cd.hanzo.ai only
This workflow ran on a self-hosted actions-runner-controller pool. ARC is
decommissioned: CI executes inside git.hanzo.ai (Gitea Actions, .hanzo/workflows)
and delivery is cd.hanzo.ai reconciling the reviewed image pin in
hanzoai/universe. GitHub is a mirror and runs nothing.

Removed rather than repointed — there is no GitHub-side pool to move to, and
leaving it would keep ARC load-bearing.
2026-07-27 08:16:32 -07:00
zeekay 3d1b0524c2 ci: remove GitHub CI — native git.hanzo.ai + cd.hanzo.ai only
This workflow ran on a self-hosted actions-runner-controller pool. ARC is
decommissioned: CI executes inside git.hanzo.ai (Gitea Actions, .hanzo/workflows)
and delivery is cd.hanzo.ai reconciling the reviewed image pin in
hanzoai/universe. GitHub is a mirror and runs nothing.

Removed rather than repointed — there is no GitHub-side pool to move to, and
leaving it would keep ARC load-bearing.
2026-07-27 08:16:30 -07:00
zeekay a1ee759a49 ci: remove GitHub CI — native git.hanzo.ai + cd.hanzo.ai only
This workflow ran on a self-hosted actions-runner-controller pool. ARC is
decommissioned: CI executes inside git.hanzo.ai (Gitea Actions, .hanzo/workflows)
and delivery is cd.hanzo.ai reconciling the reviewed image pin in
hanzoai/universe. GitHub is a mirror and runs nothing.

Removed rather than repointed — there is no GitHub-side pool to move to, and
leaving it would keep ARC load-bearing.
2026-07-27 08:16:29 -07:00
zeekay 667b0a6352 feat(telemetry): spans go to o11y over ZAP, not OTLP
kmsd built the OTLP HTTP exporter, which pulls gRPC and protobuf even on the
HTTP transport — otlptracehttp shares otlpconfig with the gRPC one.

luxfi/trace v1.3.0 exports over ZAP natively: a JSON SpanBatch inside a ZAP
envelope, read by hanzo/o11y/pkg/zapreceiver.

This module's graph is now free of both: otlp and google.golang.org/grpc are
each zero in go.mod. Knobs are O11Y_ENDPOINT / O11Y_TRACES_ENDPOINT /
O11Y_SERVICE_NAME, with O11Y_ENDPOINT=default resolving to o11y.hanzo.svc:4317.
Posture unchanged: opt-in, non-fatal, no dial at construction.
2026-07-26 18:52:15 -07:00
zeekayandHanzo Dev b3aa45d141 Merge remote-tracking branch 'origin/main' into reconcile-native
Co-authored-by: Hanzo Dev <[email protected]>
2026-07-26 17:44:26 -07:00
zeekayandHanzo Dev 3d53f3709a fix(kms-ui): truthful labels for validator key slots
The Keys page labeled the two validator slots "BLS public key" and "Corona
public key". Those names do not describe the cryptography: the "BLS" slot is
secp256k1 signed via CGGMP21 threshold ECDSA (not bls12-381), and the "Corona"
slot is ed25519 signed via FROST (not post-quantum, not the Corona R-LWE
lattice protocol). Relabel to state the actual scheme so operators are not
misled into a bls12-381/PQ assumption.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-25 17:52:27 -07:00
zeekay 7faddf8cc9 docs: modernize + LLM.md + cross-links (one-way SDK model) 2026-07-24 12:43:36 -07:00
zeekay 739e4c42af docs: modernize + LLM.md + cross-links (one-way SDK model) 2026-07-24 12:43:34 -07:00
zeekayandGitHub 5c7d586194 Merge decruft: drop dead Embedded.HTTPAddr accessor 2026-07-18 11:02:51 -07:00
zeekay a0cced206c refactor(embed): drop dead Embedded.HTTPAddr accessor
Provably-dead exported accessor: no in-repo callers (only cmd/kmsd and
mount.go consume the root package) and no external importer of
github.com/hanzoai/kms across the tree uses it. Its backing httpAddr
field was write-only and its comment was wrong (stored the raw config
addr, never a resolved listener address). Removes field, assignment,
and accessor. Build+vet green.
2026-07-18 11:02:07 -07:00
zeekay 314e415959 ci: resolve private luxfi modules in the kms release build
The binaries job built with GOPRIVATE='' so go verified the first-party
luxfi/* modules against the public sumdb — force-moved upstream tags never
match, so every release failed with 'checksum mismatch / SECURITY ERROR'
(luxfi/[email protected]). Set GOPRIVATE + GONOSUMDB for luxfi/* + hanzoai/* and add a
git-config token (GH_PAT, GITHUB_TOKEN fallback) so the modules resolve directly
via git and skip the sumdb. Dockerfile: GONOSUMCHECK (removed by Go) -> GONOSUMDB,
guard the token, x-access-token form; docker job passes GH_PAT so it can read
luxfi.
2026-07-18 09:36:19 -07:00
zeekay 7427353c76 build(deps): bump luxfi/kms v1.11.8 -> v1.12.4
Latest v1.x of the canonical KMS server. luxfi/keys (v1.4.1) and
luxfi/crypto (v1.20.2) were already at latest v1.x via the module graph.
luxfi/mpc stays out of the graph by design: threshold signing is delegated
over ZAP to an external MPC daemon (cfg.MPCAddr / MPCVaultID) through
luxfi/kms's pkg/mpc client; this module never links the standalone daemon.

GOWORK=off go build/vet/test green; test delta vs HEAD = 0.
2026-07-18 01:15:58 -07:00
zeekayandGitHub feb2c695da Merge chore/debrand-o11y-comment: debrand SigNoz -> o11y in telemetry comment 2026-07-18 00:13:38 -07:00
zeekay 3503def4a9 chore(o11y): debrand SigNoz -> o11y in telemetry comment 2026-07-18 00:13:25 -07:00
zeekayandGitHub f182722b58 Merge chore/fork-hygiene-notice: Infisical provenance + deviations in NOTICE 2026-07-18 00:08:59 -07:00
bd746663fe feat: migrate SQLite driver to hanzoai/sqlite (#25)
Swap the audit-trail SQLite driver from modernc.org/sqlite to hanzoai/
sqlite, the dual-backend drop-in that registers the "sqlite" driver name
under both CGO (mattn+SQLCipher) and !cgo (modernc) builds.

- audit.go: blank import + storage doc comment rebranded.
- red_hardening_test.go: swap the test-side blank import too. Both files
  had to move together: under CGO=1 hanzoai/sqlite registers "sqlite" via
  mattn while a lingering direct modernc import ALSO registers it, causing
  `panic: sql: Register called twice for driver sqlite` at test init.
  Swapping both leaves a single registration under both build configs.

Security: SQLite in KMS backs ONLY the plaintext audit trail (KMS_AUDIT_DB);
secrets are MPC-rooted and never stored in SQLite. The audit DB is opened
with a nil key via sql.Open("sqlite", ...&_pragma=...), so it stays
plaintext under both backends — the swap does not change the at-rest path.
DSN is already modernc-style (_pragma=NAME(VALUE)); no conversion needed.

Co-authored-by: hanzo-dev <[email protected]>
2026-07-17 22:46:12 -07:00
zeekayandHanzo Dev a750199c4d build(deps): bump kms/sdk/go luxfi/keys v1.2.0 -> v1.4.1 (ServiceIdentity consumer)
The kms Go SDK module directly imports luxfi/keys (NewServiceIdentity /
ServiceIdentity). Its v1.2.0 pin was force-moved; adopt the stable v1.4.1,
regenerate go.sum from the current remote. Builds clean (CGO_ENABLED=0).

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-17 01:00:15 -07:00
zeekayandHanzo Dev 7ccb5b437d build(deps): adopt unified luxfi stack via keys v1.4.1 (unbreak force-moved keys/zap-proto + vanished geth v1.16.98)
kms pinned luxfi/keys v1.4.0 whose remote tag was force-moved (content
5153d639→80a3745a → go.sum checksum mismatch), plus zap-proto/http v0.1.0
(also force-moved) and geth v1.16.98 (deleted tag). Only keys v1.4.1 is
byte-stable; adopting it floors the unified luxfi stack and regenerates
go.sum from the current remote. kmsd + kms (pure-Go CGO_ENABLED=0, ZapDB)
build clean; the ServiceIdentity surface (keys.NewServiceIdentity) is
unchanged (v1.4.1 = local v1.4.0 identity work + geth bump).

go.mod/go.sum only.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-17 00:59:00 -07:00
zeekay 95d86fe8e0 chore(notice): state Infisical derivation provenance and deviations; sweep product branding 2026-07-13 15:56:39 -07:00
zeekay 16cefe9254 ci: route linux/amd64 jobs to hanzo-build-linux-amd64 ARC scale set 2026-07-10 21:52:38 -07:00
8123ee23ea fix(kms): require explicit env on secret writes (no silent default) (#22)
env is a first-class component of the storage key
(kms/secrets/{path}/{env}/{name}); a POST/PATCH that omitted env used to
silently default to "default", committing the write to a bucket that
project/env/path readers (kms-operator, cluster syncs) never resolve. That
split landed an IAM z-password in env=default while prod kept serving the
stale value. POST/PATCH now fail loud with 400 when env is omitted;
GET/DELETE/LIST keep a compat default for legacy readers (a read/delete
can't plant a value another reader trusts).

Root cause on the client: sdk/go/kmsclient dropped env on every HTTP op
(c.env was used only on the ZAP path), so a client configured for env=prod
still wrote to env=default over HTTP. The HTTP path now sends c.env on the
write body and as ?env= on read/delete, matching the ZAP path. Built
in-tree via a local replace so cmd/kms and cmd/kms-fetch ship the fix; the
two Dockerfiles stage sdk/go/go.mod so `go mod download` resolves the
replaced module.

Regression tests: write without env -> 400; write env=prod is readable via
the operator's project/env/path resolution (sha256 round-trip, values never
printed) and is not visible in env=default.


Co-authored-by: hanzo-dev <[email protected]>
2026-07-08 07:21:40 -07:00
zeekayandHanzo Dev 27dd78968e build: base on ghcr.io/hanzoai/nodejs:v24.18.0 (Node 24 + sqlite3)
Adopt the canonical Hanzo Node base image. Node 24 uniform across the
fleet; sqlite3 bundled (node:sqlite builtin + native better-sqlite3
toolchain). One base, one way.

Co-authored-by: Hanzo Dev <[email protected]>
v2.6.3
2026-07-04 12:49:29 -07:00
d678d01d6a fix(kmsd): gate per-request access log behind KMS_LOG_LEVEL=debug (#21)
The zip access-log middleware logged one Info "request" line per call —
~4k lines/min, the entire KMS log volume in ClickHouse. Startup, shutdown,
authz-denials (kms_auth_reject), and handler errors are logged elsewhere and
stay at info. Default (info) is now quiet; opt back in with KMS_LOG_LEVEL=debug.

Co-authored-by: hanzo-dev <[email protected]>
2026-07-04 04:32:01 -07:00
zeekay d95c4f8f8a fix(auth): KMS login proxies to the current IAM token endpoint
IAM moved its OAuth token endpoint to /v1/iam/oauth/token; the login proxy
(and the Go SDK client) still called the retired /v1/iam/login/oauth/access_token,
which now 404s — so /v1/kms/auth/login returned 401 for every valid machine
identity. This broke fresh KMSSecret-operator logins and the hanzoai/ci deploy-
cred fetch. Point both at /v1/iam/oauth/token (form/body unchanged); update LLM.md.

Note: requires a KMS image release + redeploy (ghcr.io/luxfi/kms) to take effect.
2026-07-03 16:32:40 -07:00
zeekayandGitHub 83f15fb9fd feat(o11y): emit OTel traces via go.opentelemetry.io/otel (service.name=hanzo-kms) (#20)
Env-gated on OTEL_EXPORTER_OTLP_ENDPOINT; non-fatal; clean no-op when unset (safe to ship before the collector is live). Installs the global tracer provider with a service.name resource so the console Monitoring tab filters this product. Mirrors ai/object/telemetry.go. Traces-only; metrics/logs are a tracked follow-up.
2026-07-02 20:18:57 -07:00
zeekay 4050871bea Merge remote-tracking branch 'origin/rip/api-to-v1' 2026-07-02 13:07:26 -07:00