I came here to say that this is presumably ORE/OPE (order-revealing/preserving) encryption, not FHE, but...
It is both remarkable and depressing how _little_ information is given, and how buried it is on the CipherStash website... _any_ information on what their security and/or threat model is, what is actually stored, how encryption and search works, or any trade-offs involved.
Just to list a few pages that tell you next to nothing:
https://cipherstash.com/docs/stack/reference/what-is-ciphers...
https://cipherstash.com/docs/stack/cipherstash/encryption/se...
https://cipherstash.com/docs/stack/cipherstash/encryption
I eventually found:
https://cipherstash.com/docs/stack/reference/security-archit...
Which... it sounds like 'searched without being decrypted' means... it encrypts your query against their fast KMS and uses that to compare against indexes that were also encrypted with the same KMS? And ORE/OPE is an optional mode when you want range support.
We worked with the CipherStash team to build a Prisma Next extension that provides full type safety for their additional query shapes, and a fully managed experience for applying schema changes. It was a great experience working with the team, and we were particularly excited about this, as it helped us prove out the new extensibility mechanisms we have been working so hard for in Prisma Next.
Docs here: https://cipherstash.com/docs/stack/cipherstash/encryption/pr...
And a mention in our April update on Prisma Next: https://www.prisma.io/blog/prisma-next-roadmap-april-milesto...
If you want to give CipherStash on Supabase a try, using Prisma Next is the smoothest experience.
> Anywhere you need direct database access outside your application, CipherStash Proxy provides a secure escape hatch.
This sounds like a back door. Is it?
To me, the whole article feels super-unclear about what exactly is involved.
Can HN folks who know more weigh in?
Looking at their website, reading through abit, and seeing the comments here. Guys, this website is entirely ai generated, which might indicate about their product some. Not saying that they are lieing or anything, but expect a wall of text that no one really read through, and expect to (pun intended) cipher out the details.
James here, principal engineer at CipherStash. A few of you have (fairly) pointed out that the threat model is hard to find on our site, so rather than answer piecemeal let me lay the whole thing out. tekacs got most of the way there by reading between the lines, which is on us, not them.
The premise first: organisations shouldn't have to make a mutually exclusive choice between encrypting their data and being able to query it. That's the reason CipherStash exists, and everything below follows from it.
The threat model in one sentence: anyone with access to the database itself - dumps, backups, stolen credentials, SQLi, a hosting provider, an over-curious DBA - should learn as little as possible about sensitive values, and every legitimate decryption should require authentication and leave an audit record. We're explicitly not claiming to defend against an attacker who fully owns your running application with valid credentials. Nothing at this layer can, and anyone who tells you otherwise is selling snake oil.
The components:
* ZeroKMS: the key service. Root key material sits here, HSM-backed. Every encrypted value gets its own unique data key, but ZeroKMS never has it - keys are derived in your application from a seed we return plus a client key that never leaves your infrastructure. Two parties are needed to derive any key, so CipherStash cannot decrypt your data. Not "won't", can't.
* CTS: the token service. Exchanges tokens from your identity provider (Supabase Auth, Auth0, etc.) so decryption is bound to end-user identity rather than a service account. This is what makes the SQLi case boring: an attacker's session can only derive keys for data that user was allowed to read anyway.
* Auditing: because every decryption requires a key derivation, the key service sees every access - which value (by key ID, not content) and by whom. Query logs tell you what was asked; this tells you what was actually decrypted.
There are two ways to integrate, and you can run both:
* At the application layer, via the ORM adapters (Supabase, Prisma, Drizzle). Encryption and decryption happen inside your application process - the database only ever stores ciphertext and encrypted index terms, and plaintext exists nowhere outside your app. This is the tightest trust boundary and the mode the identity-bound stuff above is built for.
* At the SQL layer, via the Proxy - a Rust Postgres proxy that runs in your infrastructure. It encrypts and decrypts transparently, before results reach the client, so anything that speaks Postgres works unmodified: psql, BI tools, migration scripts, legacy apps you can't touch. Crucially, credentials through the Proxy are still tied to an individual identity, not a machine identity. There are two layers of auth in play: a machine credential identifies the Proxy instance itself, and the user's identity is tunnelled through it - so the engineer running psql derives keys as themselves, subject to the same access policy and audit trail as everything else. The trade-off between the two modes is where plaintext appears, not who's accountable. Escape hatch, not back door - a back door would be a bypass of the access controls - this isn't.
Key rotation is handled by the same re-encryption scheme that powers derivation: root key material can be rotated server-side without re-encrypting the data itself, because the stored ciphertexts never depended on a long-lived key sitting next to them.
On leakage, since that's the crux of the scepticism: yes, searchable encryption leaks. Equality indexes (HMAC) reveal when two values match, so frequency. Range indexes (ORE, Lewi-Wu 2016) reveal ordering. Text indexes (encrypted bloom filters) reveal probabilistic token membership. This isn't a bug we're hiding, it's the fundamental trade: for the database to use an index it has to compare something, and whatever it compares, it learns. The schemes that leak nothing (FHE, ORAM) are bullshit slow. What we've done is make the leakage bounded, documented, and opt-in per column, per query type. If the frequency or ordering of a column is itself sensitive - salaries being the classic example - don't index it. Encrypt it plainly and filter after decryption in the app. Most columns need no search at all, and the default is exactly that: no index, no leakage beyond ciphertext length.
The docs criticism lands and we're fixing it - the security architecture page (https://cipherstash.com/docs/stack/reference/security-archit...) now covers the primitives, key hierarchy and per-index leakage in one place, benchmarks are at https://github.com/cipherstash/benches, and the crypto that matters is open source and auditable: https://github.com/cipherstash/encrypt-query-language, https://github.com/cipherstash/ore.rs, https://github.com/cipherstash/proxy.
I’m having a hard time wrapping my head around what guarantees this does and does not make.
If you can run “select * where secret_col == 10”… why does it matter that the column is encrypted?