feat(secrets): cluster secrets page on the hdb_secret store#1402
feat(secrets): cluster secrets page on the hdb_secret store#1402dawsontoth wants to merge 4 commits into
Conversation
|
Warning Gemini encountered an error creating the review. You can try again by commenting |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces client-side envelope encryption (enc:v1) using the Web Crypto API to securely manage cluster-level deployment secrets, including UI components for listing, adding, and editing secrets. Feedback focuses on utilizing the query cache for the public key, adding a deletion confirmation prompt, handling non-secure contexts where the Web Crypto API is unavailable, ensuring type safety when closing the edit modal, and optimizing ArrayBuffer slicing to avoid unnecessary memory allocations.
f3a8577 to
a2827d7
Compare
f7aafe5 to
d47f200
Compare
448fef2 to
775ba23
Compare
Config > Secrets manages the replicated system.hdb_secret table (harper#1554; Pro key custody in harper-pro#512, tracked by harper-pro#166): named, envelope-encrypted rows on the cluster itself, edited through the per-instance operations API and scoped to applications via grants. - list_secrets / set_secret / delete_secret / grant_secret / revoke_secret / get_secrets_public_key hooks on the instance operations client. - Values are encrypted in the browser (enc:v1 via lib/crypto/envSecret.ts, which harper#1554 ported into core as its envelope codec) and can never be read back. Rotation-aware: the public key is cached minutes not forever, and a kid-mismatch rejection drops the cached key, re-encrypts, and retries once. - Grants editor in the edit dialog (only granted applications receive a secret at load time) and per-row warnings for rows whose kid no longer matches the cluster's custody key. - Degrades gracefully without key custody: the list stays browsable, a banner explains why nothing can be encrypted, and add/edit is disabled. - Nav entry is version-gated only (>= 5.2.0 placeholder, matching harper#1554's upgrade directive) — the store ships in core, so it is not restricted to Fabric-managed clusters. Builds on the shared SecretsManager / SecretModals components from the .env editor PR underneath this one. Hook coverage runs against real WebCrypto RSA keys, including the rotation retry re-encrypting under the newly served key. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ager central-manager#409 makes CM the custodian for hosted clusters: it mints the per-cluster RSA keypair on first use (Studio's key fetch is what triggers the mint), stamps the fingerprint onto instances, and delivers the private key to host-managers — so the public key exists and is authoritative at CM even before any node has custody registered. Fabric-managed clusters now fetch the public key via POST /ClusterSecrets (get_secrets_public_key + clusterId, camelCase response); self-hosted and local instances keep the node operation (snake_case response). Both are normalized to one shape, and the kid-mismatch retry now also heals CM's documented first-mint race (the losing key's envelopes fail with a kid mismatch; re-encrypting against the stored winner fixes them). Values are unchanged: still encrypted in the browser and submitted to the cluster's own set_secret — they never pass through or live in CM. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
73d8841 to
c481285
Compare
…on gate Harper ships the hdb_secret store in the 5.2.0 line (harper#1554); dev builds carry prerelease tags like 5.2.0-alpha.1 / 5.2.0-beta.1. Floor the Secrets nav gate at 5.2.0-alpha.1 (the earliest 5.2 prerelease) so those builds pass it — a plain '5.2.0' floor would exclude every prerelease (SemVer ranks prereleases below the release), same convention as the existing 4.7.0-beta.7 / 4.7.0-alpha.1 gates. Also type the processEnv field that list_secrets rows carry in the merged harper#1554. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
c481285 to
41cf167
Compare
Cluster secrets (hdb_secret) can be delivered two mutually-exclusive
ways (harper#1554): materialized onto process.env for every component
(global), or scoped to granted apps and read through the `secrets`
accessor. Expose that choice in the add/edit dialogs and, based on the
pick, show an inline, copy-paste-correct code example of how to read the
secret — `process.env.NAME` vs `const { NAME } = secrets` (bracket
notation for names that aren't valid JS identifiers).
- accessExample.ts: pure, name-aware example builder (+ unit tests).
- SecretDeliveryPicker / SecretAccessExample / PendingGrantsInput: the
tier radio, the copyable example, and an API-free grants collector for
the add flow (the live grant_secret editor can't run pre-creation).
- SecretModals / SecretsManager: opt-in `delivery` prop threads the tier
through onSet as { processEnv, grants }; the .env panel is unchanged.
- set_secret now sends processEnv/grants (omitted to preserve the stored
tier on a plain value rotation).
Scoped grants stay live (grant_secret/revoke_secret) in edit; env-var
rows hide the grants editor since a global secret can't be scoped.
Verified with a jsdom test driving the real dialog tree end-to-end.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
This can be ready-for-review now, since the surface we expose in Harper shouldn't change meaningfully, and no one will see this until they're rocking 5.2.0 with us. We can make more little adjustments as we see fit, too. 🥳 |
What
Config → Secrets manages the replicated
system.hdb_secretstore: named, envelope-encrypted rows on the cluster itself, edited through the per-instance operations API and scoped to applications via grants. Built on the sharedSecretsManager/SecretModalscomponents from #1409.integrations/api/instance/secrets/secrets.ts— hooks forlist_secrets/set_secret/delete_secret/grant_secret/revoke_secret, plus public-key resolution:POST /ClusterSecrets, per central-manager#409) — CM is the custodian there, and Studio's key fetch is what triggers the first-use mint. Requires cluster-update rights on first use (the mint stamps fingerprints onto instances).get_secrets_public_keyoperation (file-tier custody mints its own key).lib/crypto/envSecret.ts, theenc:v1codec harper#1554 ported into core): values are encrypted in the browser and submitted as envelopes to the cluster's ownset_secret— plaintext never reaches the operations API, the operation log, disk, or CM, and can never be read back.kidno longer matches the cluster's custody key (or storedunverified) — they may fail to decrypt until re-saved..mjsfiles #409 CM) the list stays browsable, a banner explains why, and add/edit is disabled.>= 5.2.0, matching harper#1554's upgrade directive tag) — the store ships in core, so it isn't restricted to Fabric-managed clusters.Verification
tsc,oxlint,dprintclean; full suite green (1089 tests; 6 secrets-hook tests run real WebCrypto RSA keys, asserting plaintext never appears in a request body, the CM-vs-node key routing, and the rotation retry re-encrypting under the newly served key)..mjsfiles #409): the version gate correctly hides the nav entry, and direct navigation shows the degraded state (banner, read-only, empty list) with the key fetch correctly routed to CM's/ClusterSecretsfor the managed cluster..mjsfiles #409 — covered by the hook tests until then.Notes / open items
>= 5.2.0gate matches harper#1554's upgrade directive tag; retag if that ships in a different release./ClusterSecretsisn't in the generated OpenAPI SDK yet; regenerate to type it once central-manager#409 ships.get_componentswould be a nice follow-up.ClusterSecretsstore from central-manager#405 (control-plane values + host-manager value injection). That model was superseded by the two-key custody plan (harper-pro#166 / central-manager#409: CM keeps the key, the cluster keeps the ciphertext), and this page was retargeted accordingly.🤖 Generated with Claude Code
Related PRs — secrets management
One
enc:v1:client contract everywhere (public key + envelope; values encrypted before they leave the client):.envprotection in the operations API — merged (consumed by feat(secrets): version-adaptive .env editor in the application editor #1409)enc:v1:decrypt hook + envelope contract — mergedhdb_secretstore with grant-scoped secret operations +get_secrets_public_keyfile(self-hosted) +injected(Fabric) providers; supersedes harper-pro#505.envpanel (deployable now)