EncryptionClient
The EncryptionClient is the main entry point for interacting with the CipherStash Encryption library. It provides methods for encrypting and decrypting indiv...
Class: EncryptionClient
Defined in: packages/stack/src/encryption/index.ts:71
The EncryptionClient is the main entry point for interacting with the CipherStash Encryption library. It provides methods for encrypting and decrypting individual values, as well as models (objects) and bulk operations.
The client must be initialized using the Encryption function before it can be used.
Constructors
Constructor
new EncryptionClient(): EncryptionClient;Returns
EncryptionClient
Methods
encrypt()
encrypt(plaintext, opts): EncryptOperation;Defined in: packages/stack/src/encryption/index.ts:202
Encrypt a value - returns a promise which resolves to an encrypted value.
Parameters
plaintext
JsPlaintext
The plaintext value to be encrypted.
opts
Options specifying the column (or nested field) and table for encryption. See EncryptOptions.
Returns
An EncryptOperation that can be awaited or chained with additional methods.
Examples
The following example demonstrates how to encrypt a value using the Encryption client. It includes defining an encryption schema with encryptedTable and encryptedColumn, initializing the client with Encryption, and performing the encryption.
encrypt returns an EncryptOperation which can be awaited to get a Result
which can either be the encrypted value or an EncryptionError.
// Define encryption schema
import { Encryption } from "@cipherstash/stack"
import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
const userSchema = encryptedTable("users", {
email: encryptedColumn("email"),
});
// Initialize Encryption client
const client = await Encryption({ schemas: [userSchema] })
// Encrypt a value
const encryptedResult = await client.encrypt(
"[email protected]",
{ column: userSchema.email, table: userSchema }
)
// Handle encryption result
if (encryptedResult.failure) {
throw new Error(`Encryption failed: ${encryptedResult.failure.message}`);
}
console.log("Encrypted data:", encryptedResult.data);When encrypting data, a LockContext can be provided to tie the encryption to a specific user or session. This ensures that the same lock context is required for decryption.
The following example demonstrates how to create a lock context using a user's JWT token and use it during encryption.
// Define encryption schema and initialize client as above
// Create a lock for the user's `sub` claim from their JWT
const lc = new LockContext();
const lockContext = await lc.identify(userJwt);
if (lockContext.failure) {
// Handle the failure
}
// Encrypt a value with the lock context
// Decryption will then require the same lock context
const encryptedResult = await client.encrypt(
"[email protected]",
{ column: userSchema.email, table: userSchema }
)
.withLockContext(lockContext)See
encryptQuery()
Call Signature
encryptQuery(plaintext, opts): EncryptQueryOperation;Defined in: packages/stack/src/encryption/index.ts:259
Encrypt a query value - returns a promise which resolves to an encrypted query value.
Parameters
plaintext
JsPlaintext
The plaintext value to be encrypted for querying.
opts
QueryTermBase
Options specifying the column, table, and optional queryType for encryption.
Returns
An EncryptQueryOperation that can be awaited or chained with additional methods.
Examples
The following example demonstrates how to encrypt a query value using the Encryption client.
// Define encryption schema
import { Encryption } from "@cipherstash/stack"
import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
const userSchema = encryptedTable("users", {
email: encryptedColumn("email").equality(),
});
// Initialize Encryption client
const client = await Encryption({ schemas: [userSchema] })
// Encrypt a query value
const encryptedResult = await client.encryptQuery(
"[email protected]",
{ column: userSchema.email, table: userSchema, queryType: 'equality' }
)
// Handle encryption result
if (encryptedResult.failure) {
throw new Error(`Encryption failed: ${encryptedResult.failure.message}`);
}
console.log("Encrypted query:", encryptedResult.data);The queryType can be auto-inferred from the column's configured indexes:
// When queryType is omitted, it will be inferred from the column's indexes
const encryptedResult = await client.encryptQuery(
"[email protected]",
{ column: userSchema.email, table: userSchema }
)See
JSONB columns (searchableJson):
When queryType is omitted on a searchableJson() column, the query operation is inferred:
- String plaintext →
steVecSelector(JSONPath queries like'$.user.email') - Object/Array plaintext →
steVecTerm(containment queries like{ role: 'admin' })
Call Signature
encryptQuery(terms): BatchEncryptQueryOperation;Defined in: packages/stack/src/encryption/index.ts:268
Encrypt multiple values for use in queries (batch operation).
Parameters
terms
readonly ScalarQueryTerm[]
Array of query terms to encrypt
Returns
decrypt()
decrypt(encryptedData): DecryptOperation;Defined in: packages/stack/src/encryption/index.ts:344
Decryption - returns a promise which resolves to a decrypted value.
Parameters
encryptedData
Encrypted
The encrypted data to be decrypted.
Returns
A DecryptOperation that can be awaited or chained with additional methods.
Examples
The following example demonstrates how to decrypt a value that was previously encrypted using the encrypt method. It includes encrypting a value first, then decrypting it, and handling the result.
const encryptedData = await client.encrypt(
"[email protected]",
{ column: "email", table: "users" }
)
const decryptResult = await client.decrypt(encryptedData)
if (decryptResult.failure) {
throw new Error(`Decryption failed: ${decryptResult.failure.message}`);
}
console.log("Decrypted data:", decryptResult.data);Provide a lock context when decrypting:
await client.decrypt(encryptedData)
.withLockContext(lockContext)Remarks
The public input type rejects null, but at runtime decrypt will
short-circuit and return null when given a null ciphertext
(defense in depth for legacy / manually-NULLed DB rows reached via
casts or dynamic field walking). The narrow return type holds for
any caller that respects the input contract.
See
encryptModel()
encryptModel<T, S>(input, table): EncryptModelOperation<EncryptedFromSchema<T, S>>;Defined in: packages/stack/src/encryption/index.ts:394
Encrypt a model (object) based on the table schema.
Only fields whose keys match columns defined in the table schema are encrypted.
All other fields are passed through unchanged. Returns a thenable operation
that supports .withLockContext() for identity-aware encryption.
The return type is schema-aware: fields matching the table schema are
typed as Encrypted, while other fields retain their original types. For
best results, let TypeScript infer the type parameters from the arguments
rather than providing an explicit type argument.
Type Parameters
T
T extends Record<string, unknown>
S
S extends EncryptedTableColumn = EncryptedTableColumn
Parameters
input
T
The model object with plaintext values to encrypt.
table
The table schema defining which fields to encrypt.
Returns
EncryptModelOperation<EncryptedFromSchema<T, S>>
An EncryptModelOperation that can be awaited to get a Result
containing the model with schema-defined fields typed as Encrypted,
or an EncryptionError.
Example
import { Encryption } from "@cipherstash/stack"
import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
type User = { id: string; email: string; createdAt: Date }
const usersSchema = encryptedTable("users", {
email: encryptedColumn("email").equality(),
})
const client = await Encryption({ schemas: [usersSchema] })
// Let TypeScript infer the return type from the schema.
// result.data.email is typed as `Encrypted`, result.data.id stays `string`.
const result = await client.encryptModel(
{ id: "user_123", email: "[email protected]", createdAt: new Date() },
usersSchema,
)
if (result.failure) {
console.error(result.failure.message)
} else {
console.log(result.data.id) // string
console.log(result.data.email) // Encrypted
}decryptModel()
decryptModel<T>(input): DecryptModelOperation<T>;Defined in: packages/stack/src/encryption/index.ts:436
Decrypt a model (object) whose fields contain encrypted values.
Identifies encrypted fields automatically and decrypts them, returning the
model with plaintext values. Returns a thenable operation that supports
.withLockContext() for identity-aware decryption.
Type Parameters
T
T extends Record<string, unknown>
Parameters
input
T
The model object with encrypted field values.
Returns
A DecryptModelOperation<T> that can be awaited to get a Result
containing the model with decrypted plaintext fields, or an EncryptionError.
Example
// Decrypt a previously encrypted model
const decrypted = await client.decryptModel<User>(encryptedUser)
if (decrypted.failure) {
console.error(decrypted.failure.message)
} else {
console.log(decrypted.data.email) // "[email protected]"
}
// With a lock context
const decrypted = await client
.decryptModel<User>(encryptedUser)
.withLockContext(lockContext)bulkEncryptModels()
bulkEncryptModels<T, S>(input, table): BulkEncryptModelsOperation<EncryptedFromSchema<T, S>>;Defined in: packages/stack/src/encryption/index.ts:487
Encrypt multiple models (objects) in a single bulk operation.
Performs a single call to ZeroKMS regardless of the number of models, while still using a unique key for each encrypted value. Only fields matching the table schema are encrypted; other fields pass through unchanged.
The return type is schema-aware: fields matching the table schema are
typed as Encrypted, while other fields retain their original types. For
best results, let TypeScript infer the type parameters from the arguments.
Type Parameters
T
T extends Record<string, unknown>
S
S extends EncryptedTableColumn = EncryptedTableColumn
Parameters
input
T[]
An array of model objects with plaintext values to encrypt.
table
The table schema defining which fields to encrypt.
Returns
BulkEncryptModelsOperation<EncryptedFromSchema<T, S>>
A BulkEncryptModelsOperation that can be awaited to get a Result
containing an array of models with schema-defined fields typed as Encrypted,
or an EncryptionError.
Example
import { Encryption } from "@cipherstash/stack"
import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
type User = { id: string; email: string }
const usersSchema = encryptedTable("users", {
email: encryptedColumn("email"),
})
const client = await Encryption({ schemas: [usersSchema] })
// Let TypeScript infer the return type from the schema.
// Each item's email is typed as `Encrypted`, id stays `string`.
const result = await client.bulkEncryptModels(
[
{ id: "1", email: "[email protected]" },
{ id: "2", email: "[email protected]" },
],
usersSchema,
)
if (!result.failure) {
console.log(result.data) // array of models with encrypted email fields
}bulkDecryptModels()
bulkDecryptModels<T>(input): BulkDecryptModelsOperation<T>;Defined in: packages/stack/src/encryption/index.ts:529
Decrypt multiple models (objects) in a single bulk operation.
Performs a single call to ZeroKMS regardless of the number of models, restoring all encrypted fields to their original plaintext values.
Type Parameters
T
T extends Record<string, unknown>
Parameters
input
T[]
An array of model objects with encrypted field values.
Returns
A BulkDecryptModelsOperation<T> that can be awaited to get a Result
containing an array of models with decrypted plaintext fields, or an EncryptionError.
Example
const encryptedUsers = encryptedResult.data // from bulkEncryptModels
const result = await client.bulkDecryptModels<User>(encryptedUsers)
if (!result.failure) {
for (const user of result.data) {
console.log(user.email) // plaintext email
}
}
// With a lock context
const result = await client
.bulkDecryptModels<User>(encryptedUsers)
.withLockContext(lockContext)bulkEncrypt()
bulkEncrypt(plaintexts, opts): BulkEncryptOperation;Defined in: packages/stack/src/encryption/index.ts:571
Encrypt multiple plaintext values in a single bulk operation.
Each value is encrypted with its own unique key via a single call to ZeroKMS.
Values can include optional id fields for correlating results back to
your application data.
Parameters
plaintexts
An array of objects with plaintext (and optional id) fields.
opts
Options specifying the target column (or nested encryptedField) and table. See EncryptOptions.
Returns
A BulkEncryptOperation that can be awaited to get a Result
containing an array of { id?, data: Encrypted } objects, or an EncryptionError.
Example
import { Encryption } from "@cipherstash/stack"
import { encryptedTable, encryptedColumn } from "@cipherstash/stack/schema"
const users = encryptedTable("users", {
email: encryptedColumn("email"),
})
const client = await Encryption({ schemas: [users] })
const result = await client.bulkEncrypt(
[
{ id: "u1", plaintext: "[email protected]" },
{ id: "u2", plaintext: "[email protected]" },
],
{ column: users.email, table: users },
)
if (!result.failure) {
// result.data = [{ id: "u1", data: Encrypted }, { id: "u2", data: Encrypted }, ...]
console.log(result.data)
}bulkDecrypt()
bulkDecrypt(encryptedPayloads): BulkDecryptOperation;Defined in: packages/stack/src/encryption/index.ts:608
Decrypt multiple encrypted values in a single bulk operation.
Performs a single call to ZeroKMS to decrypt all values. The result uses
a multi-status pattern: each item in the returned array has either a data
field (success) or an error field (failure), allowing graceful handling
of partial failures.
Parameters
encryptedPayloads
An array of objects with data (encrypted payload) and optional id fields.
Returns
A BulkDecryptOperation that can be awaited to get a Result
containing an array of { id?, data: plaintext } or { id?, error: string } objects,
or an EncryptionError if the entire operation fails.
Example
const encrypted = await client.bulkEncrypt(plaintexts, { column: users.email, table: users })
const result = await client.bulkDecrypt(encrypted.data)
if (!result.failure) {
for (const item of result.data) {
if ("data" in item) {
console.log(`${item.id}: ${item.data}`)
} else {
console.error(`${item.id} failed: ${item.error}`)
}
}
}getEncryptConfig()
getEncryptConfig():
| {
v: number;
tables: Record<string, Record<string, {
cast_as: "string" | "number" | "bigint" | "boolean" | "text" | "date" | "json";
indexes: {
ore?: {
};
unique?: {
token_filters?: {
kind: ...;
}[];
};
match?: {
tokenizer?: | {
kind: "standard";
}
| {
kind: "ngram";
token_length: number;
};
token_filters?: {
kind: ...;
}[];
k?: number;
m?: number;
include_original?: boolean;
};
ste_vec?: {
prefix: string;
array_index_mode?: | "all"
| "none"
| {
item?: ... | ... | ...;
wildcard?: ... | ... | ...;
position?: ... | ... | ...;
};
};
};
}>>;
}
| undefined;Defined in: packages/stack/src/encryption/index.ts:617
Get the encrypt config object.
Returns
| {
v: number;
tables: Record<string, Record<string, {
cast_as: "string" | "number" | "bigint" | "boolean" | "text" | "date" | "json";
indexes: {
ore?: {
};
unique?: {
token_filters?: {
kind: ...;
}[];
};
match?: {
tokenizer?: | {
kind: "standard";
}
| {
kind: "ngram";
token_length: number;
};
token_filters?: {
kind: ...;
}[];
k?: number;
m?: number;
include_original?: boolean;
};
ste_vec?: {
prefix: string;
array_index_mode?: | "all"
| "none"
| {
item?: ... | ... | ...;
wildcard?: ... | ... | ...;
position?: ... | ... | ...;
};
};
};
}>>;
}
| undefined
The encrypt config object.