Skip to content

feat(stack): protect-ffi 0.25.0 + auth strategy option (stacked on #496)#497

Open
coderdan wants to merge 2 commits into
feat/stack-wasm-inlinefrom
feat/stack-protect-ffi-025
Open

feat(stack): protect-ffi 0.25.0 + auth strategy option (stacked on #496)#497
coderdan wants to merge 2 commits into
feat/stack-wasm-inlinefrom
feat/stack-protect-ffi-025

Conversation

@coderdan
Copy link
Copy Markdown
Contributor

Stacked on top of #496 (feat/stack-wasm-inline) — review/merge that first; this PR's base is the #496 branch, not main.

#496 was approved but its docs referenced CS_WORKSPACE_CRN being removed. @cipherstash/protect-ffi@0.25.0 enforces the opposite: CS_WORKSPACE_CRN is the source of truth and CS_REGION is dropped. This PR bumps to 0.25.0, corrects the behaviour and docs, and adds the new auth-strategy capability.

1. protect-ffi 0.24.0 → 0.25.0

0.25.0 is breaking for both entries (per the upstream release notes: "remove any serviceToken options and CtsToken imports; set CS_WORKSPACE_CRN instead of CS_REGION"):

  • WASM (/wasm-inline)newClient(strategy, opts)newClient(opts) with strategy nested (the branch's two-arg call would break at runtime). The Encryption() config now takes workspaceCrn instead of region; the AccessKeyStrategy region is derived from the CRN (crn:<region>:<workspace-id>). CS_REGION is no longer read.
  • NodeserviceToken removed from every encrypt/decrypt/query option type. The per-operation CTS token is no longer forwarded; auth flows through the client strategy/credentials, and lock contexts still travel as lockContext.identityClaim. The public LockContext/identify() API is unchanged.

Lock-context coverage (the important bit)

The live lock-context.test.ts skips without a USER_JWT, so the serviceToken removal had no CI guard. Added lock-context-wiring.test.ts — mocks protect-ffi and asserts, for encrypt/decrypt/bulkEncrypt/bulkDecrypt/encryptQuery (single + batch)/encryptModel/decryptModel, that identityClaim reaches protect-ffi and serviceToken is never sent.

⚠️ Worth confirming in a live CTS round-trip that per-user lock-context binding behaves as intended under 0.25 — the offline tests guard the wiring, not the server-side semantics.

2. New config.strategy auth strategy (Node)

0.25 lets newClient accept an AuthStrategy. Encryption({ config: { strategy } }) now forwards it; getToken() is then used for every ZeroKMS request, taking precedence over the credentials-derived default (clientKey still used for encryption). Omitting it preserves existing behaviour.

Per discussion, this lives on init (not a separate initWithStrategy) so a future keyProvider option can land in the same config. AuthStrategy is re-exported from @cipherstash/stack.

Also updated

  • Deno e2e test, Supabase Edge example (index.ts, .env.example, README), and the wasm-e2e-tests CI job → CS_WORKSPACE_CRN.
  • e2e/wasm/deno.json protect-ffi pin → 0.25.0.
  • Changeset added.

Test plan

  • turbo run build --filter @cipherstash/stack (incl. DTS type-check)
  • 474 offline tests pass (vitest run --exclude searchable-json-pg)
  • wasm-e2e-tests green on CI (needs CS_WORKSPACE_CRN secret exposed to the job — added in this PR)
  • Live lock-context round-trip with USER_JWT to confirm per-user binding under 0.25

coderdan added 2 commits May 29, 2026 18:44
protect-ffi 0.25.0 is a breaking release for both entries:

WASM (@cipherstash/stack/wasm-inline):
- newClient(strategy, opts) -> newClient(opts) with strategy nested.
- Config takes a workspaceCrn instead of region; the AccessKeyStrategy
  region is derived from the CRN (crn:<region>:<workspace-id>). CS_REGION
  is no longer consulted; set CS_WORKSPACE_CRN.

Node:
- serviceToken removed from the encrypt/decrypt/query option types (and
  the CtsToken export). The per-operation CTS token is no longer
  forwarded; lock contexts still travel as lockContext.identityClaim.
  Public LockContext/identify() API is unchanged.

Adds offline lock-context wiring tests (mock protect-ffi) asserting every
operation forwards identityClaim and never sends serviceToken, plus
extractRegionFromCrn unit tests. Updates the Deno e2e test, Supabase
example, and wasm-e2e CI job to CS_WORKSPACE_CRN.
protect-ffi 0.25 lets newClient take an AuthStrategy (any
{ getToken(): Promise<{ token }> } object). Expose it on the Node
Encryption client via config.strategy: when supplied, getToken() is
invoked on every ZeroKMS request, taking precedence over the
credentials-derived default (clientKey is still used for encryption).
Omitting it preserves existing credentials/env behaviour.

Kept on init (rather than a separate initWithStrategy) so a future
keyProvider option can land in the same config. AuthStrategy is
re-exported from @cipherstash/stack for consumers to type their own.
@coderdan coderdan requested a review from a team as a code owner May 29, 2026 08:45
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1e97a353-ec07-461a-b000-d55f8ae1c70a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/stack-protect-ffi-025

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 29, 2026

🦋 Changeset detected

Latest commit: 2b9d376

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@cipherstash/stack Minor
@cipherstash/bench Patch
@cipherstash/prisma-next Patch
@cipherstash/basic-example Patch
@cipherstash/prisma-next-example Patch
@cipherstash/e2e Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant