Skip to content

Encrypt and search your sensitive data in PostgreSQL, with no SQL changes

License

Notifications You must be signed in to change notification settings

cipherstash/proxy

Repository files navigation

CipherStash Logo
Proxy

Implement robust data security without sacrificing performance or usability


Proxy V2 now available

Read the announcement

CipherStash Proxy provides a transparent proxy to your existing Postgres database.

Proxy:

  • Automatically encrypts and decrypts the columns you specify
  • Supports most query types over encrypted values
  • Runs in a Docker container
  • Is written in Rust and uses a formal type system for SQL mapping
  • Works with CipherStash ZeroKMS and offers up to 14x the performance of AWS KMS

Behind the scenes, it uses the Encrypt Query Language to index and search encrypted data.

Table of contents

Getting started

Important

Prerequisites: Before you start you need to have this software installed:

Get up and running in local dev in < 5 minutes:

# Clone the repo
git clone https://github.com/cipherstash/proxy
cd proxy

# Install the CipherStash CLI
## macOS
brew install cipherstash/tap/stash
## Linux
## Download from https://github.com/cipherstash/cli-releases/releases/latest

# Setup your CipherStash configuration
stash setup --proxy
# ⬆️ this outputs creds to .env.proxy.docker

# Start the containers
docker compose up

This will start a PostgreSQL database on localhost:5432, and CipherStash Proxy on localhost:6432. There's an example table called users that you can use to start inserting and querying encrypted data with.

Note

In this example table we've chosen users' email, date of birth, and salary as examples of the kind of sensitive data that you might want to protect with encryption.

Step 1: Insert and read some data

Now let's connect to the Proxy via psql and run some queries:

docker compose exec proxy psql postgres://cipherstash:3ncryp7@localhost:6432/cipherstash

This establishes an interactive session with the database, via CipherStash Proxy.

Now insert and read some data via Proxy:

INSERT INTO users (encrypted_email, encrypted_dob, encrypted_salary) VALUES ('[email protected]', '1970-01-01', '100');

SELECT encrypted_email, encrypted_dob, encrypted_salary FROM users;

The INSERT statement inserts a record into the users table, and the SELECT statement reads the same record back. Notice that it looks like nothing happened: the data in the INSERT was unencrypted, and the data in the SELECT is also unencrypted.

Now let's connect to the database directly via psql and see what the data actually looks like behind the scenes:

docker compose exec proxy psql postgres://cipherstash:3ncryp7@postgres:5432/cipherstash

This establishes an interactive session directly with the database (note the change of host to postgres and port to 5432).

Now on this direct psql session, query the database directly:

SELECT encrypted_email, encrypted_dob, encrypted_salary FROM users;

You'll see the output is much larger, because the SELECT returns the raw encrypted data. The data is transparently encrypted and decrypted by Proxy in the INSERT and SELECT statements.

Step 2: Update the data with a WHERE clause

In your psql connection to Proxy:

docker compose exec proxy psql postgres://cipherstash:3ncryp7@localhost:6432/cipherstash

Update the data we inserted in Step 1, and read it back:

UPDATE users SET encrypted_dob = '1978-02-01' WHERE encrypted_email = '[email protected]';

SELECT encrypted_dob FROM users WHERE encrypted_email = '[email protected]';

In the UPDATE statement, the = comparison operation in the WHERE clause is evaluated against encrypted data. In the SELECT statement, the encrypted_email value is transparently encrypted by Proxy, and compared in the database against the stored encrypted email value. In the SELECT statement, the SELECT returns 1978-02-01.

Back on the psql session connected directly to the database, verify the data is encrypted:

SELECT encrypted_email, encrypted_dob, encrypted_salary FROM users;

This SELECT shows the raw encrypted data — no plaintext to see.

Step 3: Search encrypted data with a WHERE clause

In your psql connection to Proxy:

docker compose exec proxy psql postgres://cipherstash:3ncryp7@localhost:6432/cipherstash

Insert more records via Proxy, and query by email:

INSERT INTO users (encrypted_email, encrypted_dob, encrypted_salary) VALUES ('[email protected]', '1991-03-06', '10');
INSERT INTO users (encrypted_email, encrypted_dob, encrypted_salary) VALUES ('[email protected]', '2005-12-30', '1000');

SELECT encrypted_email, encrypted_dob, encrypted_salary FROM users WHERE encrypted_salary <= 100;

In the INSERT statement, the salary value is transparently encrypted by Proxy, and stored in the database in encrypted form. In the SELECT statement, the encrypted_salary value is transparently encrypted and compared in the database against the stored encrypted salary value. In the SELECT statement, the <= comparison operation in the WHERE clause is evaluated against encrypted data. In the SELECT statement, the SELECT returns alice and bob, but not carol.

Query users by email:

SELECT encrypted_email, encrypted_dob, encrypted_salary FROM users WHERE encrypted_email LIKE 'alice';

The literal string alice is transparently encrypted by Proxy, and compared in the database against the stored encrypted date value. The LIKE comparison operation is evaluated against encrypted data. The SELECT will only return alice.

Finally, query users by date:

SELECT encrypted_email, encrypted_dob, encrypted_salary FROM users WHERE encrypted_dob > '2000-01-01' ;

The literal date 2000-01-01 is transparently encrypted by Proxy, and compared in the database against the stored encrypted date value. The > comparison operation is evaluated against encrypted data. The SELECT will only return carol.

Back on the psql session connected directly to the database, verify the data is encrypted:

SELECT encrypted_email, encrypted_dob, encrypted_salary FROM users;

This SELECT shows the raw encrypted data, no plaintext to see.

This demonstrates the power of CipherStash Proxy:

  • Completely transparent encryption of sensitive data in PostgreSQL
  • All data remains searchable, while being protected with non-deterministic AES-256-GCM encryption
  • Zero changes required to your application's database queries

More info

Check out our how-to guide for Proxy, or jump straight into the reference guide. For information on developing for Proxy, see the Proxy development guide.


Didn't find what you wanted?

Click here to let us know what was missing from our docs.