HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
cipherstash
encrypt-query-language
PLpgSQL2026–2026
cipherstash / encrypt-query-language · Archived

encrypt-query-language

Index and search encrypted data in PostgreSQL with SQL

2Distinct people
4Mentions
0Explicit recommenders
28GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Index and search encrypted data in PostgreSQL with SQL

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 1:49:46 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by 3-hour interval4 dated mentions

Observed mentions: 2026-07-19 08:30:08 UTC to 2026-07-22 14:08:33 UTC.

0122026-07-19 06:00:00 UTC to 2026-07-19 09:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 commentsJul 19, 06:002026-07-19 09:00:00 UTC to 2026-07-19 12:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-19 12:00:00 UTC to 2026-07-19 15:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2026-07-19 15:00:00 UTC to 2026-07-19 18:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-19 18:00:00 UTC to 2026-07-19 21:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-19 21:00:00 UTC to 2026-07-20 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-20 00:00:00 UTC to 2026-07-20 03:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-20 03:00:00 UTC to 2026-07-20 06:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-20 06:00:00 UTC to 2026-07-20 09:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-20 09:00:00 UTC to 2026-07-20 12:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-20 12:00:00 UTC to 2026-07-20 15:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-20 15:00:00 UTC to 2026-07-20 18:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-20 18:00:00 UTC to 2026-07-20 21:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-20 21:00:00 UTC to 2026-07-21 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 commentsJul 20, 21:002026-07-21 00:00:00 UTC to 2026-07-21 03:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-21 03:00:00 UTC to 2026-07-21 06:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-21 06:00:00 UTC to 2026-07-21 09:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-21 09:00:00 UTC to 2026-07-21 12:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-21 12:00:00 UTC to 2026-07-21 15:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-21 15:00:00 UTC to 2026-07-21 18:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-21 18:00:00 UTC to 2026-07-21 21:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-21 21:00:00 UTC to 2026-07-22 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-22 00:00:00 UTC to 2026-07-22 03:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-22 03:00:00 UTC to 2026-07-22 06:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-22 06:00:00 UTC to 2026-07-22 09:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-22 09:00:00 UTC to 2026-07-22 12:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2026-07-22 12:00:00 UTC to 2026-07-22 15:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 commentsJul 22, 12:00

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
Jul 19, 06:002026-07-19 06:00:00 UTC2026-07-19 09:00:00 UTC101
Jul 19, 09:002026-07-19 09:00:00 UTC2026-07-19 12:00:00 UTC000
Jul 19, 12:002026-07-19 12:00:00 UTC2026-07-19 15:00:00 UTC202
Jul 19, 15:002026-07-19 15:00:00 UTC2026-07-19 18:00:00 UTC000
Jul 19, 18:002026-07-19 18:00:00 UTC2026-07-19 21:00:00 UTC000
Jul 19, 21:002026-07-19 21:00:00 UTC2026-07-20 00:00:00 UTC000
Jul 20, 00:002026-07-20 00:00:00 UTC2026-07-20 03:00:00 UTC000
Jul 20, 03:002026-07-20 03:00:00 UTC2026-07-20 06:00:00 UTC000
Jul 20, 06:002026-07-20 06:00:00 UTC2026-07-20 09:00:00 UTC000
Jul 20, 09:002026-07-20 09:00:00 UTC2026-07-20 12:00:00 UTC000
Jul 20, 12:002026-07-20 12:00:00 UTC2026-07-20 15:00:00 UTC000
Jul 20, 15:002026-07-20 15:00:00 UTC2026-07-20 18:00:00 UTC000
Jul 20, 18:002026-07-20 18:00:00 UTC2026-07-20 21:00:00 UTC000
Jul 20, 21:002026-07-20 21:00:00 UTC2026-07-21 00:00:00 UTC000
Jul 21, 00:002026-07-21 00:00:00 UTC2026-07-21 03:00:00 UTC000
Jul 21, 03:002026-07-21 03:00:00 UTC2026-07-21 06:00:00 UTC000
Jul 21, 06:002026-07-21 06:00:00 UTC2026-07-21 09:00:00 UTC000
Jul 21, 09:002026-07-21 09:00:00 UTC2026-07-21 12:00:00 UTC000
Jul 21, 12:002026-07-21 12:00:00 UTC2026-07-21 15:00:00 UTC000
Jul 21, 15:002026-07-21 15:00:00 UTC2026-07-21 18:00:00 UTC000
Jul 21, 18:002026-07-21 18:00:00 UTC2026-07-21 21:00:00 UTC000
Jul 21, 21:002026-07-21 21:00:00 UTC2026-07-22 00:00:00 UTC000
Jul 22, 00:002026-07-22 00:00:00 UTC2026-07-22 03:00:00 UTC000
Jul 22, 03:002026-07-22 03:00:00 UTC2026-07-22 06:00:00 UTC000
Jul 22, 06:002026-07-22 06:00:00 UTC2026-07-22 09:00:00 UTC000
Jul 22, 09:002026-07-22 09:00:00 UTC2026-07-22 12:00:00 UTC000
Jul 22, 12:002026-07-22 12:00:00 UTC2026-07-22 15:00:00 UTC101

What Hacker News says

4 sources
> What does the risk profile look like in a full leak of the encrypted database? We actually have a number of different schemes which trade leakage for performance/storage overhead/compatibility. Each one has its own type in Postgres so you just create a column with whatever type you want. The weakest (most leakage) is OPE - order preserving encryption. We use an encoding scheme that works like scientific notation so an attacker with a DB snapshot would learn relative order but not the size of the gaps between values. Its major benefit is compatibility - it works everywhere. The strongest is Block ORE - Order Revealing Encryption. A DB snapshot reveals nothing more than standard randomized encryption (IND-CPA2 semantic security). The tradeoff is that BlockORE values are much bigger: 32-bit integer goes to 384 bytes. On Postgres its still
Read the rest
very fast and works with standard B-trees. > If you had a column of integers are you able to order them without decrypting? Yes. For either scheme, its just an EQL function: SELECT * FROM foo ORDER by eql_v3.ord_term(x); > Check that values are the same? -- $1: encrypt(query) SELECT * FROM foo WHERE eql_v3.eq_term(x) = eql_v3.eq_term($1); > Identify null values? NULL is just like any value for OPE/ORE - encrypt it and use that to query -- $1: encrypt(NULL) SELECT * FROM foo WHERE eql_v3.eq_term(x) = eql_v3.eq_term($1); NULL values can be encrypted with either scheme. Very safe to do so with the ORE scheme (fully randomized values). If encrypting strings, NULLs would reveal length but you can always pad if not leaking value length is important to your security model. In the OPE scheme, NULL would encrypt deterministically so if you expect a lot of NULLs in your data this could leak the distribution. We are working on a capability now called Leakage Tuned Domains. The goal here is not to eliminate leakage but scope it to a specific data type (e.g. birthdays) such that any leakage cannot be an advantage to an attacker. Think k-anonymisation or differential-privacy on steroids. Some links if you want to learn more: https://github.com/cipherstash/encrypt-query-language https://cipherstash.com/blog/fixing-a-1-in-256-bug-in-cllw-o...
In Searchable field-level encryption on Supabase with CipherStash
Thanks for all the comments. CipherStash isn't something that we just threw together on a weekend. We've spent years developing it. I've personally invested almost every waking moment for the last 6 years working on this (and the prior 2 preparing to quit my job so I could work on it full time). I get that it seems like snake oil to some. But that's just because we don't do a good enough job of explaining what we've created. We're working on that - we're engineers, not marketers. There have been prior attempts at making tech like this work, and maybe because those approaches were limited, its tainted how folks see encryption tech. We've studied many of the previous attempts and invested in the engineering required to overcome the problems. Key management - we made a 2 party key system that is faster and has a better security model than AW
Read the rest
S KMS alone. Not because we thought it was fun, not on a whim but because it was the only way to solve the real security challenges we faced when it comes to protecting data. Searchable encryption - that is less secure than homomorphic encryption but FAST. Like under a few milliseconds for most queries (homomorphic would take literally minutes or worse). And a whole lot better than no encryption at all. It uses a key per value. Encrypt query language - a framework that makes searchable encryption work in standard postgres. No exotic index schemes, no custom builds. Just SQL functions. Typescript and Rust libraries to make this _almost_ drop-in for Prisma Next, supabase-js and Drizzle. Identity integrations with Supabase, Clerk, Auth0, and Okta. A postgres proxy that automatically encrypts and decrypts data for authorized requests - for when using the SDK isn't possible/convenient. And an audit system that records every access and can send data to anything you can connect to AWS firehose or an S3 bucket. This is real and IMHO is exceptional engineering...anyone know a great technical marketer?! https://github.com/cipherstash/stack https://github.com/cipherstash/benches https://github.com/cipherstash/proxy https://github.com/cipherstash/encrypt-query-language
In Searchable field-level encryption on Supabase with CipherStash
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
Read the rest
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.
In Searchable field-level encryption on Supabase with CipherStash
CipherStash founder here: I'll cop it about the website - we're a small team so we lean on AI for marketing copy but this is a reminder that we need to do better. The tech is the result of 6 years of work. We're a team of 8 engineers and have been working on it full time thanks to VC funding. I'm obviously biased but its legit tech. We've invested in making it fast, secure and able to support most common query patterns. Our github repos might be better than our website but I'll certainly admit that our docs/marketing needs some work! Checkout out: https://github.com/cipherstash/stack https://github.com/cipherstash/encrypt-query-language https://github.com/cipherstash/proxy
In Searchable field-level encryption on Supabase with CipherStash

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.