Implement robust data security without sacrificing performance or usability
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.
Important
Prerequisites: Before you start you need to have this software installed:
- Docker — see Docker's documentation for installing
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.
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.
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.
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
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.