You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
security: Invariant #14 durableBindings has zero server-side readers — enforcement lives entirely in the agent it distrusts (#460 closed on the producer half) #812
Verified against canonical agenthill main 504dac0.
Defect
src/security/durable-binding.ts is 96 lines: DurableBindingKind enum, makeDurableBinding factory, canned provenance strings. No comparison. No validation. No throw.
Producers write it — morpho ×6, uniswap-v3 ×3, btc multisig (:432). Readers: zero in src/signing/ or src/security/.
The nuance that makes it worse, not better
durable-binding.ts:11-15 states by design that the skill consumes it. So this is not an oversight — it is a named security invariant (#14) whose entire enforcement lives in the agent.
That is the one party Invariant #14 exists to distrust.
#460 closed on the producer half. The consumer half is the half that enforces anything, and it is outside the trust boundary.
Why it matters
A binding that is only ever written and never read is indistinguishable, at runtime, from not existing. A compromised or lazy agent skips the check and nothing in the server notices. The invariant reads as enforced in the code and in docs; it is not.
Verified against canonical
agenthillmain504dac0.Defect
src/security/durable-binding.tsis 96 lines:DurableBindingKindenum,makeDurableBindingfactory, canned provenance strings. No comparison. No validation. No throw.Producers write it — morpho ×6, uniswap-v3 ×3, btc multisig (
:432). Readers: zero insrc/signing/orsrc/security/.The nuance that makes it worse, not better
durable-binding.ts:11-15states by design that the skill consumes it. So this is not an oversight — it is a named security invariant (#14) whose entire enforcement lives in the agent.That is the one party Invariant #14 exists to distrust.
#460 closed on the producer half. The consumer half is the half that enforces anything, and it is outside the trust boundary.
Why it matters
A binding that is only ever written and never read is indistinguishable, at runtime, from not existing. A compromised or lazy agent skips the check and nothing in the server notices. The invariant reads as enforced in the code and in docs; it is not.
Options
userDecisionproblem)Same class as #763 / #766: a named guarantee whose code does not deliver it.
Related: #460 (closed on producer half), #763, #766.