Files
zeekayandGitHub 6ab565e2ba feat(transport): add ZAP-native transport alongside HTTP (#2)
Introduces a kmsapi.Transport interface so the reconciler can talk to
the canonical luxfi/kms surface over either JSON-over-HTTP or the
binary ZAP wire (opcodes 0x0040..0x0043) on the same KMS daemon.

Why: sub-100µs in-cluster secret CRUD for the operator, on the same
authoritative store as the HTTP path. The HTTP transport stays the
default — ZAP is opt-in per KMSSecret/KMSPushSecret via host scheme:
  http(s)://…           → kmsapi.Client (today's path, unchanged)
  zap://host:port       → kmszap.Client (new, NodeID-bound)
  zap+mdns://_kms._tcp  → kmszap.Client (mDNS discovery)

Auth model — important divergence from HTTP, documented in
packages/kmszap/client.go: ZAP authorises by peer NodeID + ACL
(KMS_ZAP_ACL), not by IAM bearer token. Operator deployments wanting
ZAP MUST register their NodeID with the kmsd ACL. clientId/clientSecret
on the CR's universalAuth credentialsRef are ignored on the ZAP path
(the call still works because Login() returns a synthetic
"zap:<nodeID>" token kept by the existing token cache).

Files:
  packages/kmsapi/transport.go      — Transport interface, IsZAPHost
  packages/kmszap/client.go         — ZAP-backed kmsapi.Transport impl
  packages/util/transport.go        — shared BuildTransport factory
  controllers/kmssecret  + kmspushsecret — use util.BuildTransport
  packages/util/{auth,secrets,models}.go — signatures use Transport
2026-05-30 20:23:15 -07:00

33 lines
724 B
Go

package kmsapi
import (
"testing"
)
func TestIsZAPHost(t *testing.T) {
cases := []struct {
host string
want bool
}{
{"http://kms.hanzo.ai", false},
{"https://kms.hanzo.ai/api", false},
{"kms.hanzo.svc.cluster.local", false},
{"", false},
{"zap://kms.hanzo.svc:9999", true},
{"ZAP://Kms.Hanzo.Svc:9999", true}, // case-insensitive
{"zap+mdns://_kms._tcp", true},
{" zap://kms:9999 ", true}, // whitespace tolerated
}
for _, c := range cases {
t.Run(c.host, func(t *testing.T) {
if got := IsZAPHost(c.host); got != c.want {
t.Fatalf("IsZAPHost(%q) = %v, want %v", c.host, got, c.want)
}
})
}
}
func TestClientImplementsTransport(t *testing.T) {
var _ Transport = (*Client)(nil)
}