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
The wasm-inline entry cannot produce or read identity-bound ciphertext. lockContext appears in packages/stack/src/wasm-inline.ts exactly once — in a comment stating it is absent (:665) — and nowhere in the implementation.
This looks like a port gap rather than a deliberate limitation, and the way it is currently explained compounds it.
Authentication and lock context are orthogonal — the current framing conflates them
wasm-inline.ts:665 says there is no .withLockContext() because "identity-bound encryption on the edge is configured at client construction via config.authStrategy instead". skills/stash-edge repeats this as "Identity-bound encryption is configured, not chained."
That is not what an auth strategy does. There are two separate mechanisms on the native entry:
Authentication — OidcFederationStrategy as config.authStrategy. Authenticates the client as the end user. This is the part that changed: per-operation CTS tokens were removed in protect-ffi 0.25, and LockContext.identify() is deprecated accordingly (identity/index.ts:119).
Key binding — .withLockContext({ identityClaim }). Binds the data key to a claim, per operation. This did not go away and is still required to get identity-bound encryption.
What changed on native is (1). config.authStrategy replaced the old token-fetching ceremony — it did not replace .withLockContext(). The WASM entry picked up (1) and not (2), and the comment then described the gap as if (1) subsumed (2).
The capability exists below the wrapper
protect-ffi 0.30 accepts a lock context on both the single and bulk paths:
The WASM binding's opts are typed any (dist/wasm/protect_ffi.d.ts) because they cross a serde boundary into the same Rust core, so the shape is almost certainly already accepted — it is simply not typed or plumbed on the JS side. Worth confirming against the Rust before scoping the work.
Impact
Data written from an edge function cannot be identity-bound at all.
Data written on Node with a lock context cannot be decrypted on the edge, because decrypt needs the same lock context. That is a silent split in what the two entries can read, on top of the schema nominal-typing incompatibility already documented in skills/stash-edge.
Supabase Edge Functions are the flagship WASM use case and the most likely place to want per-user key binding, since the JWT is right there.
Suggested work
Confirm the WASM binding accepts lockContext in its serde payloads.
Plumb it through WasmEncryptionClient — .withLockContext() if the chainable shape is wanted, or a per-call option consistent with whatever this entry settles on (see the bulk-shape issue).
Fix wasm-inline.ts:665 regardless of whether the feature lands: it currently teaches that an auth strategy is identity-bound encryption, which is wrong on both entries.
The
wasm-inlineentry cannot produce or read identity-bound ciphertext.lockContextappears inpackages/stack/src/wasm-inline.tsexactly once — in a comment stating it is absent (:665) — and nowhere in the implementation.This looks like a port gap rather than a deliberate limitation, and the way it is currently explained compounds it.
Authentication and lock context are orthogonal — the current framing conflates them
wasm-inline.ts:665says there is no.withLockContext()because "identity-bound encryption on the edge is configured at client construction viaconfig.authStrategyinstead".skills/stash-edgerepeats this as "Identity-bound encryption is configured, not chained."That is not what an auth strategy does. There are two separate mechanisms on the native entry:
OidcFederationStrategyasconfig.authStrategy. Authenticates the client as the end user. This is the part that changed: per-operation CTS tokens were removed in protect-ffi 0.25, andLockContext.identify()is deprecated accordingly (identity/index.ts:119)..withLockContext({ identityClaim }). Binds the data key to a claim, per operation. This did not go away and is still required to get identity-bound encryption.What changed on native is (1).
config.authStrategyreplaced the old token-fetching ceremony — it did not replace.withLockContext(). The WASM entry picked up (1) and not (2), and the comment then described the gap as if (1) subsumed (2).The capability exists below the wrapper
protect-ffi 0.30 accepts a lock context on both the single and bulk paths:
The WASM binding's
optsare typedany(dist/wasm/protect_ffi.d.ts) because they cross a serde boundary into the same Rust core, so the shape is almost certainly already accepted — it is simply not typed or plumbed on the JS side. Worth confirming against the Rust before scoping the work.Impact
skills/stash-edge.Suggested work
lockContextin its serde payloads.WasmEncryptionClient—.withLockContext()if the chainable shape is wanted, or a per-call option consistent with whatever this entry settles on (see the bulk-shape issue).wasm-inline.ts:665regardless of whether the feature lands: it currently teaches that an auth strategy is identity-bound encryption, which is wrong on both entries.skills/stash-edge(landing in feat(cli): add the stash-postgres and stash-edge skills — raw-SQL predicates and the WASM entry #777) — same error, and it ships to customers.Docs note
The relationship between the two mechanisms is not clearly stated anywhere. Splitting it out into a dedicated auth skill is tracked separately.