Files
base/examples
zeekayandHanzo Dev 8fab4b95db Base reads its master key from KMS, over the door KMS serves
There were two ways to hold one thing. PRINCIPAL_ENCRYPTION_KEY carried a
32-byte master key through the environment into a Secret beside the pod, and
KMSEndpoint named a KMS that was supposed to hold it. Only the first worked,
because the client spoke ZAP and refused an http endpoint at construction —
and no KMS in this estate serves ZAP. So the deployment set
KMS_URL=http://kms.hanzo.svc, Register returned that refusal, and the env key
was the only path left. A field named Deprecated sat beside it, read through a
two-branch accessor, which is a third spelling of the same value.

Now: one key, one coordinate, one credential.

- httpSecrets implements the existing secrets interface over /v1/kms. The
  transport is a detail behind that interface, which is why adding one is not
  adding a second way to read a secret.
- It authenticates as an IAM application using the client credentials this
  plugin already holds to talk to IAM. One identity per Base, not two.
- The org leads the path on the ZAP side because that segment is the base
  boundary. Over HTTP the org comes from the credential and another tenant's
  secret is unnameable, so the prefix is dropped rather than composed twice.
- PrincipalEncryptionKey, its Deprecated twin and principalKey() are gone. The
  master key is read at Register from base/MASTER_KEY_B64 under the org.
- Absent stays non-fatal: no KMS, or no key stored, runs with encryption off
  exactly as an unset variable did.

Also dropped the default endpoint zap.kms.svc.cluster.local:9999. Nothing
answers there, so it turned "this deployment has no KMS" — which callers handle
— into a transport error on every read. Unset now means unset.

The HTTP-rejection test asserted the belief that caused this; it now asserts
what is true, that the door needs a credential. Added a coordinate test for the
org-segment drop.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 11:46:12 -07:00
..