Skip to content
Security
Skill

/stash-prisma

Integrate CipherStash searchable field-level encryption with Prisma Next using @cipherstash/stack-prisma (EQL v3). Covers the full 31-constructor catalog of domain-named encrypted column types in schema.prisma (per plaintext type × capability tier —

BOOST
From plugin
stack
16116 skills1 command
Install
$ npx -y skills add cipherstash/stack --skill stash-prisma --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-prisma

Context preview

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

Integrate CipherStash searchable field-level encryption with Prisma Next using @cipherstash/stack-prisma (EQL v3). Covers the full 31-constructor catalog of domain-named encrypted column types in schema.prisma (per plaintext type × capability tier —

SKILL.md

stash-prisma.SKILL.md
name: stash-prisma
description: Integrate CipherStash searchable field-level encryption with Prisma Next using @cipherstash/stack-prisma (EQL v3). Covers the full 31-constructor catalog of domain-named encrypted column types in schema.prisma (per plaintext type × capability tier — Text/TextEq/TextOrd/TextMatch/TextSearch, Integer/Smallint/BigInt/Numeric/Real/Double × Eq/Ord, Date/Timestamp × Eq/Ord, Boolean, Json), the one-call cipherstashFromStack wiring, the runtime value envelopes (EncryptedString/Number/BigInt/Date/Boolean/Json) and decryptAll, the eql* query operators (eqlEq, eqlMatch, eqlGt, eqlBetween, eqlIn, eqlJsonContains, eqlAsc/eqlDesc, eqlJsonPathAsc/eqlJsonPathDesc), EQL bundle installation via prisma-next migrate, and authentication. Use when adding encryption to a Prisma Next project, upgrading @cipherstash/stack-prisma, choosing a column type, or querying encrypted columns.

CipherStash Stack — Prisma Next Integration

Guide for searchable field-level encryption in a **Prisma Next** app with `@cipherstash/stack-prisma` (EQL v3), powered by `@cipherstash/stack`. You declare encrypted columns directly in `schema.prisma`; Prisma Next's migration system installs the EQL bundle in the same sweep that creates your tables — there is no separate `stash eql install` step.

> `@cipherstash/stack-prisma` is **EQL v3 only** — there is no EQL v2 surface. > Everything below is v3.

In EQL v3 every encrypted column is a **concrete Postgres domain** (`public.eql_v3_text_search`, `public.eql_v3_double_ord`, …) whose query capabilities are fixed by the column type you choose — there is no capability config object. See the `stash-encryption` skill for the domain catalog and capability semantics; this skill covers the Prisma-Next-specific surface.

When to Use This Skill

  • Adding field-level encryption to a Prisma Next project
  • Declaring encrypted columns in `schema.prisma`
  • Querying encrypted columns with the `eql*` operators
  • Wiring the runtime with `cipherstashFromStack`

Installation

npm install @cipherstash/stack @cipherstash/stack-prisma

Or run `npx stash init --prisma`, which detects Prisma Next, installs both packages pinned to the CLI release, and authenticates. It does **not** scaffold the wiring files — Prisma Next derives its schema from `contract.json`, so there is no encryption-client file to generate; init prints the next steps (declare encrypted columns, emit the contract, run the migration) instead.

The three wiring points

1. Declare encrypted columns in `schema.prisma`

The column types are **domain-named** — the name encodes the query capability (matching the `@cipherstash/stack` `types.*` catalog), not a generic primitive:

model User {
  id            String @id
  email         cipherstash.TextSearch()  // eq + range + free-text + ORDER BY
  salary        cipherstash.DoubleOrd()   // eq + range + ORDER BY
  accountId     cipherstash.BigIntOrd()   // eq + range + ORDER BY
  birthday      cipherstash.DateOrd()     // eq + range + ORDER BY
  emailVerified cipherstash.Boolean()     // storage-only (no operators)
  preferences   cipherstash.Json()        // containment (@>)
}

The example shows six types; the **full catalog is 31 constructors** — one per exposed `public.eql_v3_*` domain, derived mechanically from the domain registry. Pick by **plaintext TypeScript type first**, then by the queries you need:

| Plaintext (TS type) | Storage-only | Equality | Order + range | Free-text | Everything | |---|---|---|---|---|---| | `string` | `Text()` | `TextEq()` | `TextOrd()` | `TextMatch()` | `TextSearch()` | | `number` (int4) | `Integer()` | `IntegerEq()` | `IntegerOrd()` | — | — | | `number` (int2) | `Smallint()` | `SmallintEq()` | `SmallintOrd()` | — | — | | `bigint` (int8) | `BigInt()` | `BigIntEq()` | `BigIntOrd()` | — | — | | `number` (numeric) | `Numeric()` | `NumericEq()` | `NumericOrd()` | — | — | | `number` (float4) | `Real()` | `RealEq()` | `RealOrd()` | — | — | | `number` (float8) | `Double()` | `DoubleEq()` | `DoubleOrd()` | — | — | | `Date` (date) | `Date()` | `DateEq()` | `DateOrd()` | — | — | | `Date` (timestamp) | `Timestamp()` | `TimestampEq()` | `TimestampOrd()` | — | — | | `boolean` | `Boolean()` | — | — | — | — | | JSON document | `Json()` — searchable JSON: containment + JSONPath equality/range/ORDER BY | | | | |

Reading the table:

  • Each constructor maps 1:1 to the domain named after it:

`IntegerOrd()` → `eql_v3_integer_ord`, `Text()` → `eql_v3_text`, and so on (`Json()` → `eql_v3_json_search`).

  • **Every `*Ord` domain includes equality** (equality + range + ORDER BY);

every `*Eq` domain is equality only; the bare family name is storage-only (encrypt/decrypt, no operators). `TextMatch` is free-text **only** — no equality. `TextSearch` carries all three text capabilities.

  • **The plaintext type matters as much as the capability.** Money stored as

integer cents wants `IntegerOrd()` (JS `number`) — not `DoubleOrd()` (float semantics) and not `BigIntOrd()`, whose plaintext is a JS `bigint` and rejects `number` values.

  • The `*OrdOre` variants exist in the database bundle but are deliberately

not exposed as constructors (their btree opclass is superuser-gated — see `stash-indexing`).

The type is fixed at the column — there is no capability tuner. A value you only store and decrypt can use a storage-only domain; a value you filter or sort needs the matching `*Eq` / `*Ord` / text-search domain.

2. Register the extension pack in `prisma-next.config.ts`

Since Prisma Next 0.17 an application depends on exactly one database facade (`@prisma/orm-postgres`; the retired `@prisma-next/*` scope no longer publishes), and the facade's `defineConfig` wires the family, target, adapter, driver, and PSL provider internally:

import cipherstash from '@cipherstash/stack-prisma/control'
import { defineConfig } from '@prisma/orm-postgres/config'

export default defineConfig({
  contr
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…