-
Notifications
You must be signed in to change notification settings - Fork 989
fix(blog): rename CipherStash post slug to prisma-8 and refresh copy #8150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,18 +1,20 @@ | ||
| --- | ||
| title: "Search encrypted data with Prisma 8 and CipherStash" | ||
| slug: "search-encrypted-data-with-prisma-next-and-cipherstash" | ||
| slug: "search-encrypted-data-with-prisma-8-and-cipherstash" | ||
| date: "2026-07-30" | ||
| authors: | ||
| - "Dan Draper" | ||
| metaTitle: "Search encrypted data with Prisma 8 and CipherStash" | ||
| metaDescription: "CipherStash brings searchable field-level encryption to Prisma 8: encrypted equality, free-text and range queries, and identity-based key management." | ||
| heroImagePath: "/search-encrypted-data-with-prisma-next-and-cipherstash/imgs/hero.svg" | ||
| heroImagePath: "/search-encrypted-data-with-prisma-8-and-cipherstash/imgs/hero.svg" | ||
| heroImageAlt: "Search encrypted data with Prisma 8 and CipherStash" | ||
| metaImagePath: "/search-encrypted-data-with-prisma-next-and-cipherstash/imgs/meta.png" | ||
| metaImagePath: "/search-encrypted-data-with-prisma-8-and-cipherstash/imgs/meta.png" | ||
| canonicalUrl: "https://cipherstash.com/blog/search-encrypted-data-with-prisma-next-and-cipherstash" | ||
| tags: | ||
| - "announcement" | ||
| - "orm" | ||
| series: prisma-next | ||
| seriesIndex: 12 | ||
| --- | ||
|
|
||
| Most developers think their production database is already encrypted. | ||
|
|
@@ -21,7 +23,7 @@ Strictly speaking, they're right. | |
|
|
||
| Most managed databases enable **encryption at rest** by default. But encryption at rest probably doesn't protect data in the way you think it does. | ||
|
|
||
| Today, we're excited to announce first-class support for **[Prisma 8 RC1](https://pris.ly/pn-cipherstash)**, making it simple to add searchable field-level encryption to Prisma applications—with encrypted queries, identity-based key management and almost no change to the way you work with your database. | ||
| Today, we're excited to announce first-class support for **[Prisma 8](https://pris.ly/pn-cipherstash)**, now in Early Access, making it simple to add searchable field-level encryption to Prisma applications—with encrypted queries, identity-based key management and a small, explicit API surface for encrypted reads and writes. This guest post by CipherStash is the twelfth entry in the [Prisma 8 series](/series/prisma-next); the integration it introduces grew out of the earlier [call for extension authors](/prisma-next-call-for-extension-authors). | ||
|
|
||
| But first: why encrypt fields at all? | ||
|
|
||
|
|
@@ -76,10 +78,9 @@ CipherStash approaches the problem differently. | |
| When enabled for a field, every sensitive value is encrypted independently using its own derived data key. | ||
| Data keys are not stored alongside the data and never leave the application. | ||
|
|
||
| Queries on EQL columns are encrypted in the same way. | ||
| Postgres compares encrypted query terms against encrypted values. | ||
| Standard B-tree and GIN indexes work, too, so performance is sub-millisecond for many queries, even on very large datasets. | ||
| See our [benchmarks][benchmarks] for more information. | ||
| Queries on encrypted columns are encrypted in the same way. | ||
| Alongside the randomized ciphertext, the [Encrypt Query Language][eql] (EQL) package stores encrypted index terms that Postgres can compare without ever seeing plaintext. The terms reveal equality, ordering, and match relationships to the database, but not the values themselves. | ||
| Standard B-tree and GIN indexes work on those terms: in our [benchmarks][benchmarks], encrypted lookups run in 0.1–0.8 ms — equality through JSON containment — on tables of up to 10 million rows. | ||
|
|
||
| This means encrypted fields can still support: | ||
|
|
||
|
|
@@ -93,16 +94,16 @@ CipherStash can also tie key access directly to the user's identity. | |
| It works with identity providers like Clerk, Auth0, and others, using the user's identity token to control access to encrypted data. | ||
| Applications don't need to store reusable data keys, and a database credential alone isn't enough to decrypt identity-bound values. | ||
|
|
||
|  | ||
|  | ||
|
|
||
| _Encrypted insert, query and decryption paths._ | ||
|
|
||
| ## Searchable encryption in Prisma 8 | ||
|
|
||
| ORMs have long supported encrypting fields. | ||
| What they haven't been able to do is preserve the queries that make an ORM useful. | ||
| What they generally haven't preserved is the queries that make an ORM useful. | ||
|
|
||
| Prisma 8 changes that. | ||
| Prisma 8's extension model changes that, letting CipherStash bring searchable encryption into the ORM's own type-safe query API. | ||
|
|
||
| <Quotes | ||
| speakerImgLink="/blog/authors/will-madden.png" | ||
|
|
@@ -127,12 +128,12 @@ For example, a `User` model might use the `Text`, `Date`, and `Json` types from | |
| model User { | ||
| id String @id | ||
| email cipherstash.Text() // encrypted string | ||
| birthday cipherstash.Date() // encrypted Date | ||
| preferences cipherstash.Json() // encrypted JSON "blob" | ||
| birthday cipherstash.Date() // encrypted date | ||
| preferences cipherstash.Json() // searchable encrypted JSON | ||
| } | ||
| ``` | ||
|
|
||
| Unlike regular plaintext types, CipherStash encrypted types are not searchable. To enable searchable encryption on a field, you can use a type variant. | ||
| The constructor is the capability set. Base types like `cipherstash.Text()` and `cipherstash.Date()` are storage-only: you can write and decrypt those columns, but not query them. To enable searchable encryption on a field, use a variant that carries the query capabilities you need. (`cipherstash.Json()` already supports encrypted containment queries.) | ||
|
|
||
| For example, for encrypted text values that support sorting, simple lookups, and fuzzy text search, use the TextSearch type: | ||
|
|
||
|
|
@@ -147,7 +148,7 @@ model User { | |
| The contract is the single source of truth for which fields are encrypted and how they can be queried (or not). | ||
| Prisma 8 manages the encrypted column types, database extension, and searchable indexes through the same migration lifecycle as the rest of your schema. | ||
|
|
||
| Each encrypted type and all its variants are installed in Postgres automatically from the [Encrypt Query Language][eql] (EQL) package. | ||
| Each encrypted type and all its variants are installed in Postgres automatically from the [EQL][eql] package. | ||
| EQL also provides functions and operators that Prisma 8 uses for query comparisons and sorting. | ||
|
|
||
| ### Encrypted queries that look like Prisma queries | ||
|
|
@@ -170,6 +171,8 @@ PostgreSQL receives an encrypted query and evaluates it against the encrypted in | |
| The same model supports free-text and range queries: | ||
|
|
||
| ```typescript | ||
| import { eqlAsc } from "@cipherstash/stack-prisma/runtime" | ||
|
|
||
| // Search for email addresses containing 'dan' | ||
| // and order results | ||
| const users = await db.orm.public.User | ||
|
|
@@ -189,15 +192,17 @@ Query results remain encrypted until the application explicitly decrypts them. | |
| ```typescript | ||
| import { decryptAll } from "@cipherstash/stack-prisma/runtime" | ||
|
|
||
| const users = // query | ||
| const users = await db.orm.public.User | ||
| .where(user => user.email.eqlEq("dan@example.com")) | ||
| .all() | ||
|
|
||
| await decryptAll(users) | ||
| const email = await users[0].email.decrypt() | ||
| ``` | ||
|
|
||
| This creates a clear boundary around plaintext access. | ||
|
|
||
| Encrypted values cannot accidentally appear in a JSON response, application log, or AI prompt simply because an object was serialized. Reaching plaintext requires an explicit decryption operation in application code. | ||
| Plaintext values cannot accidentally appear in a JSON response, application log, or AI prompt simply because an object was serialized: serialized results contain only ciphertext. Reaching plaintext requires an explicit decryption operation in application code. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
printf '%s\n' '--- relevant files ---'
git ls-files | rg '(^|/)(package\.json|pnpm-lock\.yaml|yarn\.lock|package-lock\.json|search-encrypted-data-with-prisma-8-and-cipherstash/index\.mdx)$' || true
printf '%s\n' '--- CipherStash references ---'
rg -n -i 'cipherstash|serialized|ciphertext|decryptAll|eqlAsc' . \
-g '!node_modules' -g '!dist' -g '!build' | head -n 240
printf '%s\n' '--- target article context ---'
target=$(git ls-files | rg 'apps/blog/content/blog/search-encrypted-data-with-prisma-8-and-cipherstash/index\.mdx$' | head -n 1)
if [ -n "${target:-}" ]; then
sed -n '185,215p' "$target"
fiRepository: prisma/web Length of output: 18346 🌐 Web query:
💡 Result: In the CipherStash ecosystem, specifically when using Citations:
Describe serialized encrypted values precisely.
🤖 Prompt for AI Agents |
||
|
|
||
| ## Use cases | ||
|
|
||
|
|
@@ -213,19 +218,19 @@ Organizations use CipherStash to: | |
| - reduce the impact of application or database compromise | ||
| - enforce data sovereignty and residency requirements | ||
|
|
||
| As regulators and enterprise customers increasingly expect evidence of technical controls, encryption is becoming less about protecting storage and more about proving who could—and couldn't—access sensitive information. | ||
| As regulators and enterprise customers increasingly expect evidence of technical controls, encryption is becoming less about protecting storage and more about demonstrating who could—and couldn't—access sensitive information. | ||
|
|
||
| ## Built for the Prisma stack | ||
|
|
||
| The integration works with Prisma Postgres and fits naturally into applications deployed with Prisma Compute. | ||
| The integration works with [Prisma Postgres](https://www.prisma.io/docs/postgres) and fits naturally into applications deployed with [Prisma Compute](https://www.prisma.io/docs/compute), currently in Public Beta. | ||
|
|
||
|  | ||
|  | ||
|
|
||
| _Prisma Studio browsing the same table an attacker would: the encrypted columns are ciphertext, all the way down._ | ||
|
|
||
|  | ||
|  | ||
|
|
||
| _Encrypted queries in the Prisma Postgres dashboard, running sub-millisecond alongside everything else._ | ||
| _Encrypted queries in the Prisma Postgres dashboard, running alongside everything else._ | ||
|
|
||
| ## Get started in four steps | ||
|
|
||
|
|
@@ -241,25 +246,26 @@ This gives you a fresh project with the contract-first workflow already wired up | |
|
|
||
| ### 2. Create a Prisma Postgres database | ||
|
|
||
| The scaffold connects your app to Prisma Postgres as part of setup. There's no proxy to deploy and no database extension to install by hand — Prisma 8 installs the [EQL][eql] package for you during migration, alongside your own schema. | ||
| The scaffold can connect your app to Prisma Postgres during setup. There's nothing else to deploy and no database extension to install by hand — Prisma 8 installs the [EQL][eql] package for you during migration, alongside your own schema. | ||
|
|
||
| If you'd rather stay local while you experiment, `npx prisma dev` gives you a local Postgres instance instead. | ||
| If you'd rather stay local while you experiment, `npx prisma dev` — part of the standard `prisma` CLI — gives you a local Postgres instance instead. | ||
|
|
||
| ### 3. Add the CipherStash extension | ||
|
|
||
| ```sh | ||
| npx stash init --prisma | ||
| ``` | ||
|
|
||
| This detects Prisma 8, installs `@cipherstash/stack` and `@cipherstash/stack-prisma` pinned to the CLI release, and signs you in to CipherStash. Register the extension pack in your Prisma config: | ||
| This sets up the Prisma integration: it installs `@cipherstash/stack` and `@cipherstash/stack-prisma` pinned to the CLI release and signs you in to CipherStash. Register it in your Prisma config: | ||
|
|
||
| ```typescript | ||
| // prisma-next.config.ts | ||
| import cipherstash from '@cipherstash/stack-prisma/control' | ||
| import { defineConfig } from '@prisma-next/postgres/config' | ||
|
|
||
| export default defineConfig({ | ||
| // ...your existing config | ||
| extensionPacks: [cipherstash], | ||
| extensions: [cipherstash], | ||
| }) | ||
| ``` | ||
|
|
||
|
|
@@ -294,7 +300,7 @@ model User { | |
| } | ||
| ``` | ||
|
|
||
| Then emit the contract, plan the migration, and apply it: | ||
| Then emit the contract, plan the migration, and apply it — the Early Access CLI ships these commands under the `prisma-next` binary: | ||
|
|
||
| ```sh | ||
| npx prisma-next contract emit | ||
|
|
@@ -332,13 +338,13 @@ await decryptAll(users); | |
| const email = await users[0].email.decrypt(); | ||
| ``` | ||
|
|
||
| Four steps, and the value was never in plaintext in your database, in your query, or in your logs. | ||
| Four steps, and the value never reached your database in plaintext — not in storage, not in the SQL Postgres received, and not in anything Postgres logged. | ||
|
|
||
| You can also skip the scaffold and clone the [example app](https://github.com/cipherstash/stack/tree/main/examples/prisma) instead. | ||
|
|
||
| :::note[Prisma 8 RC1] | ||
| :::note[Prisma 8 Early Access] | ||
|
|
||
| Prisma 8 is currently a release candidate. See [the Prisma 8 announcement](https://pris.ly/pn-cipherstash) for what's in it and where it's heading. | ||
| Prisma 8 is currently in Early Access. See [the Early Access announcement](/prisma-next-early-access-write-your-contract-prompt-your-agent-ship-your-app) for what's in it and where it's heading. | ||
|
|
||
| ::: | ||
|
|
||
|
|
@@ -347,7 +353,7 @@ Prisma 8 is currently a release candidate. See [the Prisma 8 announcement](https | |
| Searchable encryption does more than protect sensitive values. | ||
| It changes what applications can prove about data access. | ||
|
|
||
| When every value is encrypted independently, every query is encrypted, and every decryption is authorized against the identity making the request, access control moves from the application perimeter to the data itself. | ||
| When every value is encrypted independently, every query is encrypted, and decryption can be authorized against the identity making the request, access control moves from the application perimeter to the data itself. | ||
|
|
||
| This is known as Data Level Access Control (DLAC). | ||
|
|
||
|
|
@@ -366,7 +372,7 @@ Without searchable encryption, encrypted data becomes difficult to use. Without | |
| Together, they make it possible to build applications where access is enforced cryptographically, not just by convention. | ||
|
|
||
| This is only the beginning. | ||
| In the coming months, we'll introduce Access Intelligence, making those cryptographic decisions observable so that developers, security teams, and auditors can understand not only who accessed sensitive data but also why, when, and under what authority. | ||
| In the coming months, CipherStash will introduce Access Intelligence, making those cryptographic decisions observable so that developers, security teams, and auditors can understand not only who accessed sensitive data but also why, when, and under what authority. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🌐 Web query:
💡 Result: CipherStash Access Intelligence refers to the platform's capability to make data access decisions observable, allowing security teams, auditors, and developers to monitor and understand data access patterns, including the who, what, when, why, and under what authority data was accessed [1]. This functionality builds upon the platform's core audit logging and encryption-in-use features [2][1]. The platform's approach to access-event logging is characterized by the following: Core Logging Components: The CipherStash platform, particularly when using CipherStash Proxy, generates comprehensive data access events [3]. These events typically include: - Identity: The authenticated user or service performing the action (derived from Lock Contexts) [2][4]. - Operation Details: The specific action taken (e.g., encrypt, decrypt) [2]. - Scope: Which encrypted columns or records were accessed [2][4]. - Timing: Precise timestamps of when the operation occurred [3][2]. - Context: The application environment and query patterns used [2][5]. Advanced Proxy Audit Features: CipherStash Proxy enhances these logs through a transparent, automated pipeline that does not require instrumentation of application SQL code [3][6]: - Statement Fingerprinting: Automatically identifies unique SQL query patterns [3][2]. - SQL Redaction: Strips sensitive values from logged queries to maintain privacy [3][2]. - Primary Key Injection: Transparently injects missing primary keys into SQL statements to ensure accurate tracking of which specific records are accessed [3][2]. - Record Reconciliation: Maps extracted identifiers to specific database tables, ensuring the audit trail reflects exact record-level access [3][2]. Cryptographic Verifiability: A key distinction of the CipherStash audit trail is its cryptographic foundation [2]. Because access is controlled via identity-bound keys (ZeroKMS) and Lock Contexts, the resulting logs are not merely circumstantial application logs, but provide a cryptographically verifiable proof of access [2][7][5]. This ensures that access events cannot be easily falsified or bypassed, aiding in regulatory compliance (e.g., GDPR, HIPAA, SOC 2) [2][4]. Essentially, Access Intelligence leverages these immutable, cryptographically proven event logs to provide high-level observability into the security posture of sensitive data [1][8][9]. Citations:
🌐 Web query:
💡 Result: The exact search returned no results. The relevant CipherStash Platform page describes:
CipherStash’s glossary further defines data access events as including statement metadata and the records accessed. (cipherstash.com) Citations:
Use present-tense wording for Access Intelligence. CipherStash currently describes Access Intelligence and access-event logging as platform capabilities. Replace “will introduce ... in the coming months” with present-tense wording, or limit the future-tense claim to the Prisma integration. 🤖 Prompt for AI Agents |
||
|
|
||
| That's where we believe data security is heading, not just encrypted databases, but data that can enforce and prove its own access controls. | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Limit the benchmark claim to the measured query shapes.
The linked report shows 0.1–0.8 ms for exact and JSON cases at 10 million rows. Match and ORE/range cases are slower. The report also measures query-only latency without decryption. Name the exact and JSON cases and state the measurement boundary. (github.com)
🤖 Prompt for AI Agents