Summary
@cipherstash/nextjs is built around fetching a CTS token per request and handing it to new LockContext({ ctsToken }). Encryption operations no longer consume a CTS token, so as far as I can tell that middleware now has no effect on key derivation. Either the package needs a deprecation path, or the docs need to explain when it is still required.
I could not resolve this from the published artifacts, so this is a question rather than a bug report.
What the packages say
@cipherstash/nextjs v4.1.1 (published 2026-07-08) exports:
getCtsToken(oidcToken?) → { success, ctsToken?: { accessToken, expiry } }
protectMiddleware(oidcToken, req, res?)
protectClerkMiddleware(auth, req) (from @cipherstash/nextjs/clerk)
resetCtsToken(res?), CS_COOKIE_NAME
All CTS-token shaped.
Meanwhile @cipherstash/stack 0.19.0 dist/identity/index.d.ts deprecates getLockContext() with:
Encryption operations no longer consume a CTS token — they read the identity claim directly via identityContext.
and deprecates identify() with:
Per-operation CTS tokens were removed in protect-ffi 0.25. [...] The token fetched here is no longer used by encryption operations.
LockContextOptions still accepts ctsToken, so new LockContext({ ctsToken }) still constructs. But if .withLockContext() resolves only identityContext, the supplied token is inert, and the value ends up bound to the default { identityClaim: ["sub"] } resolved against whatever identity the client's auth strategy authenticated as — not against the token the middleware fetched.
If that reading is right, an app using protectClerkMiddleware + getCtsToken + new LockContext({ ctsToken }) and no OidcFederationStrategy is authenticating to ZeroKMS as its service credentials, not as the end user, while appearing to do identity-aware encryption.
Questions
- Is
new LockContext({ ctsToken }) still honoured for key derivation, or is the token ignored?
- Is
@cipherstash/nextjs still the recommended path for Clerk on Next.js, or is it superseded by passing the Clerk session token straight to OidcFederationStrategy?
- If superseded: does the package get a deprecation notice, or a rewrite that builds an
OidcFederationStrategy from the Next.js request?
What the docs now say
Pending an answer, cipherstash/docs#57 rewrites the Clerk/Next.js section to hand the Clerk session token directly to OidcFederationStrategy:
import { auth } from "@clerk/nextjs/server"
import { Encryption, OidcFederationStrategy } from "@cipherstash/stack"
const client = await Encryption({
schemas: [users],
config: {
authStrategy: OidcFederationStrategy.create(
process.env.CS_WORKSPACE_CRN,
async () => {
const { getToken } = await auth()
return await getToken()
},
),
},
})
with a note that protectClerkMiddleware / getCtsToken belong to the earlier CTS-token flow and are not required for identity-aware encryption. Please correct that note if it's wrong — it's currently my inference from the type definitions, not something I could confirm against the runtime.
Environment
@cipherstash/nextjs 4.1.1
@cipherstash/stack 0.19.0
@cipherstash/auth 0.42.0
@cipherstash/protect-ffi 0.28.0
Related: #591, #592.
Summary
@cipherstash/nextjsis built around fetching a CTS token per request and handing it tonew LockContext({ ctsToken }). Encryption operations no longer consume a CTS token, so as far as I can tell that middleware now has no effect on key derivation. Either the package needs a deprecation path, or the docs need to explain when it is still required.I could not resolve this from the published artifacts, so this is a question rather than a bug report.
What the packages say
@cipherstash/nextjsv4.1.1 (published 2026-07-08) exports:getCtsToken(oidcToken?)→{ success, ctsToken?: { accessToken, expiry } }protectMiddleware(oidcToken, req, res?)protectClerkMiddleware(auth, req)(from@cipherstash/nextjs/clerk)resetCtsToken(res?),CS_COOKIE_NAMEAll CTS-token shaped.
Meanwhile
@cipherstash/stack0.19.0dist/identity/index.d.tsdeprecatesgetLockContext()with:and deprecates
identify()with:LockContextOptionsstill acceptsctsToken, sonew LockContext({ ctsToken })still constructs. But if.withLockContext()resolves onlyidentityContext, the supplied token is inert, and the value ends up bound to the default{ identityClaim: ["sub"] }resolved against whatever identity the client's auth strategy authenticated as — not against the token the middleware fetched.If that reading is right, an app using
protectClerkMiddleware+getCtsToken+new LockContext({ ctsToken })and noOidcFederationStrategyis authenticating to ZeroKMS as its service credentials, not as the end user, while appearing to do identity-aware encryption.Questions
new LockContext({ ctsToken })still honoured for key derivation, or is the token ignored?@cipherstash/nextjsstill the recommended path for Clerk on Next.js, or is it superseded by passing the Clerk session token straight toOidcFederationStrategy?OidcFederationStrategyfrom the Next.js request?What the docs now say
Pending an answer, cipherstash/docs#57 rewrites the Clerk/Next.js section to hand the Clerk session token directly to
OidcFederationStrategy:with a note that
protectClerkMiddleware/getCtsTokenbelong to the earlier CTS-token flow and are not required for identity-aware encryption. Please correct that note if it's wrong — it's currently my inference from the type definitions, not something I could confirm against the runtime.Environment
@cipherstash/nextjs4.1.1@cipherstash/stack0.19.0@cipherstash/auth0.42.0@cipherstash/protect-ffi0.28.0Related: #591, #592.