--- status: open opened: 2026-09-04 located-in: [] fixed-by: amended-design: --- # A provider module's runtime needs a seal key the mesh cannot deliver ## What was observed Building the vertical slice for the module runtime (the module runs its own code as its own process under its own account), a **provider** module — one that stands up a per-consumer resource and hands back a credential — was assigned to a node and run as a broker-bound runtime. The runtime hosts the module's provisioner, and the provisioner's reconcile harness opens with: - it requires a **seal key**, read from the environment, and fails immediately without one; - every credential it produces for a consumer is **sealed to that key** before it is written. Nothing in the control plane delivers such a key to a module's runtime. The mesh delivers a module its **broker account** (a sealed, machine-bound credential) and its **own-secrets**, and it seals those deliveries with a key of its own — but there is no provision for handing a provider the key it must seal *its own* outputs with, nor for a consumer to receive the matching key to unseal them. The consequence has two faces, both bad: - **A provider runtime cannot start.** The harness treats the missing key as a hard, up-front failure — correctly, because a provider that silently sealed to nothing would be worse. So a provider module, assigned and pushed, comes up dead until a key is supplied out of band. - **Supplying one out of band is not a fix.** A key set by hand on the provider is a key the consumer has no principled way to obtain. The seal is symmetric; the two ends must share it, and there is nothing that makes them share it. The slice proved the mechanism only by setting a lab-local key in the manifest by hand — an admission, not a solution. The test that does so says as much in its header. ## Why it matters beyond this instance The module-runtime design (the ADR that says a module runs its own code under its own account) is the model every provider now follows — a cache, an object store, a database, each stands up per-consumer resources and returns sealed credentials. The delivery the mesh already does for a broker account is exactly the shape a seal key needs, so the gap is not that the idea is hard; it is that one required secret in the provider/consumer handshake was never given an owner. Left open, every provider converted to the runtime model inherits a module that cannot come up as delivered, and the failure lands at assignment time on whoever is standing up the node — far from the design decision that caused it. There is also a **rule-with-no-check** here: the design states that a consumer receives a sealed credential and unseals it. Nothing today establishes the key that makes "unseal" possible, so the rule is, at present, enforced by nothing. ## Open questions - Whose secret is the seal key — the mesh's, the node's, or the specific provider/consumer grant's? The answer decides who generates it and who it is delivered to. - Is it one key the mesh holds and delivers to both ends of every grant, or a per-grant key minted when a grant is made? A per-grant key confines a leak to one consumer; a mesh-wide key is one thing to deliver and rotate. - Should it be delivered the way the broker account already is — a sealed, machine-bound own-secret file the runtime reads — so a provider needs no new delivery channel, only a new named secret? - Does rotation of this key have to re-seal every outstanding credential, and if so, is that the provisioner's reconcile loop's job or the control plane's?