Summary
EncryptedQueryBuilder.withLockContext() accepts only a LockContext instance, while every core encryption operation accepts LockContextInput (LockContext | Context). The Supabase adapter is the odd one out, and the inconsistency pushes users toward code that looks like the deprecated identity flow even when it isn't.
Detail
dist/supabase/index.d.ts:
withLockContext(lockContext: LockContext): EncryptedQueryBuilder<T, FK>;
dist/encryption/index.d.ts (and every other operation: EncryptOperation, DecryptOperation, EncryptModelOperation, DecryptModelOperation, BulkEncryptOperation, BulkDecryptOperation, BulkEncryptModelsOperation, BulkDecryptModelsOperation, EncryptQueryOperation, BatchEncryptQueryOperation):
withLockContext(lockContext: LockContextInput): EncryptOperationWithLockContext;
where
type LockContextInput = LockContext | Context; // Context = { identityClaim: string[] }
The LockContext class docstring explicitly says constructing one is optional:
You can pass a plain { identityClaim } directly — constructing a LockContext is optional.
That's true everywhere except the Supabase path.
Why it matters
Post-protect-ffi 0.25, the recommended flow is OidcFederationStrategy plus a plain claim object:
await client
.encrypt(value, { column: users.email, table: users })
.withLockContext({ identityClaim: ["sub"] }) // ✅
On the Supabase adapter the equivalent does not typecheck, so the docs have to say:
const lockContext = new LockContext({ context: { identityClaim: ["sub"] } })
await eSupabase
.from("users", users)
.insert({ email: "alice@example.com" })
.withLockContext(lockContext) // ⚠️ only shape that compiles
Two costs. The Supabase integration page now reads differently from every other page for no semantic reason. And new LockContext(...) appearing in Supabase examples is easily mistaken for the deprecated new LockContext() → identify() flow, which is exactly the pattern we're trying to retire (see #591).
Suggested fix
Widen the adapter to accept LockContextInput and route it through the existing resolveLockContext() helper, which already normalises both shapes synchronously:
declare function resolveLockContext(input: LockContextInput): Context;
This is source-compatible: existing callers passing a LockContext keep working.
Worth checking whether the Drizzle and DynamoDB adapters have the same narrowing.
Environment
@cipherstash/stack 0.19.0
@cipherstash/protect-ffi 0.28.0
Surfaced while updating the docs in cipherstash/docs#57. Related: #591.
Summary
EncryptedQueryBuilder.withLockContext()accepts only aLockContextinstance, while every core encryption operation acceptsLockContextInput(LockContext | Context). The Supabase adapter is the odd one out, and the inconsistency pushes users toward code that looks like the deprecated identity flow even when it isn't.Detail
dist/supabase/index.d.ts:dist/encryption/index.d.ts(and every other operation:EncryptOperation,DecryptOperation,EncryptModelOperation,DecryptModelOperation,BulkEncryptOperation,BulkDecryptOperation,BulkEncryptModelsOperation,BulkDecryptModelsOperation,EncryptQueryOperation,BatchEncryptQueryOperation):where
The
LockContextclass docstring explicitly says constructing one is optional:That's true everywhere except the Supabase path.
Why it matters
Post-
protect-ffi0.25, the recommended flow isOidcFederationStrategyplus a plain claim object:On the Supabase adapter the equivalent does not typecheck, so the docs have to say:
Two costs. The Supabase integration page now reads differently from every other page for no semantic reason. And
new LockContext(...)appearing in Supabase examples is easily mistaken for the deprecatednew LockContext()→identify()flow, which is exactly the pattern we're trying to retire (see #591).Suggested fix
Widen the adapter to accept
LockContextInputand route it through the existingresolveLockContext()helper, which already normalises both shapes synchronously:This is source-compatible: existing callers passing a
LockContextkeep working.Worth checking whether the Drizzle and DynamoDB adapters have the same narrowing.
Environment
@cipherstash/stack0.19.0@cipherstash/protect-ffi0.28.0Surfaced while updating the docs in cipherstash/docs#57. Related: #591.