Identity-aware encryption
Tie encryption to a user's JWT so only that user can decrypt their data
Identity-aware encryption
Lock encryption to a specific user by requiring a valid JWT for decryption. When a value is encrypted with a lock context, it can only be decrypted by presenting the same user's identity token.
How it works
- Create a
LockContextinstance. - Identify the user with their JWT.
- Pass the lock context to encrypt and decrypt operations.
Basic usage
import { LockContext } from "@cipherstash/stack/identity"
// 1. Create a lock context (defaults to the "sub" claim)
const lc = new LockContext()
// 2. Identify the user with their JWT
const identifyResult = await lc.identify(userJwt)
if (identifyResult.failure) {
throw new Error(identifyResult.failure.message)
}
const lockContext = identifyResult.data
// 3. Encrypt with lock context
const encrypted = await client
.encrypt("sensitive data", { column: users.email, table: users })
.withLockContext(lockContext)
// 4. Decrypt with the same lock context
const decrypted = await client
.decrypt(encrypted.data)
.withLockContext(lockContext)Supported operations
Lock contexts work with all encrypt and decrypt operations:
// Single operations
const encrypted = await client
.encryptModel(user, users)
.withLockContext(lockContext)
const decrypted = await client
.decryptModel(encryptedUser)
.withLockContext(lockContext)
// Bulk operations
const bulkEncrypted = await client
.bulkEncryptModels(userModels, users)
.withLockContext(lockContext)
const bulkDecrypted = await client
.bulkDecryptModels(encryptedUsers)
.withLockContext(lockContext)Custom identity claims
Override the default context by specifying which identity claims to use:
const lc = new LockContext({
context: {
identityClaim: ["sub"], // this is the default
},
})| Identity claim | Description |
|---|---|
sub | The user's subject identifier |
scopes | The user's scopes set by your IDP policy |
Using with Clerk and Next.js
If you're using Clerk as your identity provider, install the @cipherstash/nextjs package for automatic CTS token setup.
npm install @cipherstash/nextjsSet up middleware
In your middleware.ts, use protectClerkMiddleware to automatically generate CTS tokens for every user session:
import { clerkMiddleware } from "@clerk/nextjs/server"
import { protectClerkMiddleware } from "@cipherstash/nextjs/clerk"
export default clerkMiddleware(async (auth, req) => {
return protectClerkMiddleware(auth, req)
})Retrieve the CTS token
Use getCtsToken to get the CTS token for the current user:
import { getCtsToken } from "@cipherstash/nextjs"
export default async function Page() {
const ctsToken = await getCtsToken()
if (!ctsToken.success) {
// handle error
}
// ctsToken is ready to use
}Create a LockContext with an existing CTS token
Since the CTS token is already available from the middleware, construct the LockContext directly:
import { LockContext } from "@cipherstash/stack/identity"
import { getCtsToken } from "@cipherstash/nextjs"
export default async function Page() {
const ctsToken = await getCtsToken()
if (!ctsToken.success) {
// handle error
}
const lockContext = new LockContext({ ctsToken })
// Use lockContext with encrypt/decrypt operations
}