mirror of
https://github.com/hanzoai/kms-operator.git
synced 2026-10-30 18:32:57 +00:00
Drops the legacy github.com/luxfi/kms-go SDK (Infisical-derived) and
moves every HTTP call onto the canonical surface served by
~/work/hanzo/kms cmd/kmsd at kms.hanzo.ai:
POST /v1/kms/auth/login {clientId, clientSecret}
GET /v1/kms/orgs/{org}/secrets/{path...}/{name}?env= Authorization: Bearer
POST /v1/kms/orgs/{org}/secrets upsert
PATCH /v1/kms/orgs/{org}/secrets/{path...}/{name} version CAS via If-Match
DELETE /v1/kms/orgs/{org}/secrets/{path...}/{name}?env=
The canonical server exposes no list endpoint and no opaque secret ID,
so KMSSecret now requires an explicit secretsScope.keys roster and
KMSPushSecret tracks managed names directly. The KMSDynamicSecret CRD
and controller are removed — the canonical server has no
dynamic-secrets / lease routes.
New packages/kmsapi in-tree HTTP client mirrors the lux/operator Rust
hardening profile (commit 7164368):
* Bearer token cache keyed on SHA-256(clientId|clientSecret|host).
A swapped host or rotated credential invalidates the entry
atomically. 60s refresh skew, 1h default TTL.
* Hijack guard: tokens are bound to the host that minted them.
* Control-byte rejection on every URL-relevant input and every
response value (NUL + C0 except TAB/LF/CR). PEM blobs pass; NUL
never does.
* Input bounds: host ≤512, slug ≤64, path ≤256, name ≤128 chars,
≤128 keys/CR.
* Empty-fetch fail-closed: KMSSecret refuses to project an empty
Secret on the read path.
* Same-namespace credentialsRef enforcement: a CR in namespace A
cannot read a Secret from a privileged namespace it does not own.
* 4 MiB hard cap on response bodies, 15s per-request timeout.
CRD changes (KMSSecret.spec.authentication.universalAuth.secretsScope):
+ keys: []string (required, ≥1, ≤128) — explicit fetch roster
- recursive: bool — no list endpoint exists
Forward break only: every other auth strategy (service token, service
account, K8s/AWS/Azure/GCP machine identity) and the
KMSDynamicSecret CRD are gone, with no env-flag fallbacks. Restore
each only when kmsd grows the corresponding canonical route.
go test ./... passes, including 28 new unit tests in packages/kmsapi
covering hijack guard, control-byte rejection, scope bounds, version
CAS, 404 -> ErrNotFound, 409 -> ErrVersionConflict, and the full
HTTP request/response shape against httptest.
39 lines
1.3 KiB
Go
39 lines
1.3 KiB
Go
// Package api holds the cross-controller configuration shared by every
|
|
// reconciler — the canonical luxfi/kms host, an optional custom CA, and
|
|
// the User-Agent string sent on every outbound request.
|
|
//
|
|
// All HTTP work itself lives in packages/kmsapi, which targets the
|
|
// canonical /v1/kms/* surface served by ~/work/hanzo/kms cmd/kmsd. This
|
|
// package owns no transport state.
|
|
package api
|
|
|
|
import "os"
|
|
|
|
// USER_AGENT_NAME identifies the operator on every outbound request. KMS
|
|
// audit rows store this verbatim under the actor row.
|
|
const USER_AGENT_NAME = "kms-operator"
|
|
|
|
// API_HOST_URL is the canonical luxfi/kms endpoint. Override per-deployment
|
|
// via the KMS_API_HOST_URL env var, per-cluster via the kms-config
|
|
// ConfigMap, or per-resource via spec.hostAPI on the KMSSecret /
|
|
// KMSPushSecret CR.
|
|
//
|
|
// kmsd serves all routes at the root; the legacy "/api" suffix is stripped
|
|
// at use-site by kmsapi.NormaliseHost.
|
|
var API_HOST_URL string
|
|
|
|
// API_CA_CERTIFICATE is an optional PEM bundle trusted in addition to the
|
|
// system roots. Set per-resource via spec.tls.caRef.
|
|
var API_CA_CERTIFICATE string
|
|
|
|
func init() {
|
|
if url := os.Getenv("KMS_API_HOST_URL"); url != "" {
|
|
API_HOST_URL = url
|
|
} else {
|
|
API_HOST_URL = "https://kms.hanzo.ai"
|
|
}
|
|
if ca := os.Getenv("KMS_API_CA_CERTIFICATE"); ca != "" {
|
|
API_CA_CERTIFICATE = ca
|
|
}
|
|
}
|