Skip to content
Security
Skill

/stash-encryption

Implement field-level encryption with @cipherstash/stack using the EQL v3 typed schema. Covers the types.* column catalog, the generic EncryptionClient, encrypt/decrypt and model operations, searchable encryption, encrypted JSON, bulk operations, identity-aware encryption,

BOOST
From plugin
stack
16116 skills1 command
Install
$ npx -y skills add cipherstash/stack --skill stash-encryption --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/stash-encryption

Context preview

The summary Claude sees to decide when to auto-load this skill.

Implement field-level encryption with @cipherstash/stack using the EQL v3 typed schema. Covers the types.* column catalog, the generic EncryptionClient, encrypt/decrypt and model operations, searchable encryption, encrypted JSON, bulk operations, identity-aware encryption,

SKILL.md

stash-encryption.SKILL.md
name: stash-encryption
description: Implement field-level encryption with @cipherstash/stack using the EQL v3 typed schema. Covers the types.* column catalog, the generic EncryptionClient, encrypt/decrypt and model operations, searchable encryption, encrypted JSON, bulk operations, identity-aware encryption, multi-tenant keysets, and the rollout/cutover lifecycle.

CipherStash Stack - Encryption

Comprehensive guide for implementing field-level encryption with `@cipherstash/stack`. Every value is encrypted with its own unique key via ZeroKMS (backed by AWS KMS). Encryption happens client-side before data leaves the application.

Encrypted columns are **EQL v3 concrete Postgres domains** (`public.eql_v3_text_search`, `public.eql_v3_integer_ord`, ...): each column's query capabilities are fixed by the domain type you pick in the schema, and the `Encryption` client (typed for an all-v3 schema set) derives precise TypeScript types from that schema — wrong-typed plaintext is a compile error, not a runtime surprise.

> EQL v2 is a **read-compatibility path only**. The v2 schema builders and the `@cipherstash/stack/client` subpath have been removed; `decrypt` / `decryptModel` still read stored v2 payloads so existing deployments keep working — see "Legacy: EQL v2" at the end. Author every schema and every new write with the v3 surface this skill describes.

When to Use This Skill

  • Adding field-level encryption to a TypeScript/Node.js project
  • Defining encrypted table schemas with the `types.*` domain catalog
  • Encrypting and decrypting individual values or entire models
  • Implementing searchable encryption (equality, free-text, range, encrypted JSON)
  • Bulk encrypting/decrypting large datasets
  • Implementing identity-aware encryption with JWT-based lock contexts
  • Setting up multi-tenant encryption with keysets
  • Rolling encryption out to a production table with live plaintext data

Quick Start

import { Encryption } from "@cipherstash/stack"
import { encryptedTable, types } from "@cipherstash/stack/v3"

const users = encryptedTable("users", {
  email: types.TextSearch("email"),
})

const client = await Encryption({ schemas: [users] })

const encrypted = await client.encrypt("secret@example.com", {
  table: users,
  column: users.email,
})
if (encrypted.failure) {
  throw new Error(encrypted.failure.message)
}

const decrypted = await client.decrypt(encrypted.data)

Installation

npm install @cipherstash/stack

> **Version note:** `npx stash init` is the preferred install path — it pins > every `@cipherstash/*` package to the versions matching your CLI release. > If you install manually as above, verify what actually resolved > (`node -p "require('@cipherstash/stack/package.json').version"`): bare > dist-tag installs can lag behind a release, and `stash init` will warn on > the version skew.

> [!IMPORTANT] > **Exclude `@cipherstash/stack` from bundling — required for any project with a bundler (Next.js, webpack, esbuild, vite SSR, etc.).** The package wraps a native FFI module (`@cipherstash/protect-ffi`) that cannot be bundled. Importing the encryption client from server code without this exclusion will fail at runtime with errors about missing native modules. Configure as soon as you install the package; do not skip this step.

Concrete configuration for the most common bundlers:

**Next.js** (`next.config.{js,ts,mjs}`):

const nextConfig = {
  serverExternalPackages: ['@cipherstash/stack', '@cipherstash/protect-ffi'],
}
export default nextConfig

(Older Next.js — pre-15 — uses `experimental.serverComponentsExternalPackages` with the same value.)

**webpack** (next/nuxt/remix/etc. that compose webpack directly):

config.externals.push('@cipherstash/stack', '@cipherstash/protect-ffi')

**esbuild**:

{ external: ['@cipherstash/stack', '@cipherstash/protect-ffi'] }

**Vite SSR**:

ssr: { external: ['@cipherstash/stack', '@cipherstash/protect-ffi'] }

If you skip this step, you'll see runtime errors like `Cannot find module '@cipherstash/protect-ffi-darwin-arm64'` or `dlopen failed` once the bundler tries to inline the native binding.

Configuration

Local Development (preferred: `stash auth login`)

No environment variables are needed for local development:

npx stash init        # agent-assisted setup: auth + schema + database, end to end
# or, if the project is already set up:
npx stash auth login  # device code flow; token saved to ~/.cipherstash/auth.json

`npx stash init` is the assisted flow — it authenticates, builds the encryption schema with you, generates the client file, and wires the database. For an already-initialized project, `npx stash auth login` alone authenticates the machine; the SDK and CLI pick up the saved profile automatically. Sign up at [cipherstash.com/signup](https://cipherstash.com/signup) first.

Agents can drive the login too: `npx stash auth login --json --region <slug>` emits the verification URL as data — run it in the background, relay the URL to the human, and the flow completes when they approve in a browser. The event contract and the operational loop are in the `stash-cli` skill's Authentication section.

CI and Production (environment variables)

Deployed environments and CI use machine credentials via environment variables (set in your hosting platform or pipeline secrets — not committed `.env`):

CS_WORKSPACE_CRN=crn:ap-southeast-2.aws:your-workspace-id
CS_CLIENT_ID=your-client-id
CS_CLIENT_KEY=your-client-key
CS_CLIENT_ACCESS_KEY=your-access-key

Mint all four from your device session with `npx stash env --name <name>` — no dashboard copy-paste. It creates a fresh ZeroKMS client plus a **member-role** access key (shown exactly once; the CLI cannot mint admin keys) and prints the block above, ready to pipe into your platform's secret store. `CS_CLIENT_KEY` and `CS_CLIENT_ACCESS_KEY` are secrets — never commit them. Also the path

Read more
Ships withstack

Searchable, application-level encryption for building privacy-first apps

Get the whole plugin

Other skills on stack.

stash-auth
Skill

stash-auth

How a CipherStash client authenticates — the canonical skill for credentials, auth strategies, and lock context. Covers the…

stash-cli
Skill

stash-cli

Drive CipherStash setup and encryption migrations through the `stash` CLI — `init`, `plan`, `impl`, `status`, `auth login`, `eql…