Skip to content

Commit bee65ab

Browse files
authored
Merge pull request #176 from cipherstash/add-example-statements-to-docs
docs: add example database queries to the Proxy getting started
2 parents dce33e4 + 0eb02b5 commit bee65ab

File tree

5 files changed

+204
-5
lines changed

5 files changed

+204
-5
lines changed

README.md

Lines changed: 116 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,126 @@ stash setup --proxy
7979

8080
# Start the containers
8181
docker compose up
82+
```
83+
84+
This will start a PostgreSQL database on `localhost:5432`, and CipherStash Proxy on `localhost:6432`.
85+
There's an example table called `users` that you can use to start inserting and querying encrypted data with.
86+
87+
> [!NOTE]
88+
> 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.
89+
90+
### Step 1: Insert and read some data <a id='getting-started-step-1'></a>
91+
92+
Now let's connect to the Proxy via `psql` and run some queries:
93+
94+
```bash
95+
docker compose exec proxy psql postgres://cipherstash:3ncryp7@localhost:6432/cipherstash
96+
```
8297

83-
# TODO: Run a query
84-
psql postgres://${CS_DATABASE__USERNAME}:${CS_DATABASE__PASSWORD}@localhost:6432/cipherstash
98+
This establishes an interactive session with the database, via CipherStash Proxy.
8599

86-
# TODO: Verify the data is encrypted
87-
psql postgres://${CS_DATABASE__USERNAME}:${CS_DATABASE__PASSWORD}@postgres:5432/cipherstash
100+
Now insert and read some data via Proxy:
101+
102+
```sql
103+
INSERT INTO users (encrypted_email, encrypted_dob, encrypted_salary) VALUES ('alice@cipherstash.com', '1970-01-01', '100');
104+
105+
SELECT encrypted_email, encrypted_dob, encrypted_salary FROM users;
106+
```
107+
108+
The `INSERT` statement inserts a record into the `users` table, and the `SELECT` statement reads the same record back.
109+
Notice that it looks like nothing happened: the data in the `INSERT` was unencrypted, and the data in the `SELECT` is also unencrypted.
110+
111+
Now let's connect to the database directly via `psql` and see what the data actually looks like behind the scenes:
112+
113+
```bash
114+
docker compose exec proxy psql postgres://cipherstash:3ncryp7@postgres:5432/cipherstash
88115
```
89116

117+
This establishes an interactive session directly with the database (note the change of host to `postgres` and port to `5432`).
118+
119+
Now on this direct `psql` session, query the database directly:
120+
121+
```sql
122+
SELECT encrypted_email, encrypted_dob, encrypted_salary FROM users;
123+
```
124+
125+
You'll see the output is _much_ larger, because the `SELECT` returns the raw encrypted data.
126+
The data is transparently encrypted and decrypted by Proxy in the `INSERT` and `SELECT` statements.
127+
128+
### Step 2: Update the data with a `WHERE` clause <a id='getting-started-step-2'></a>
129+
130+
In your `psql` connection to Proxy:
131+
132+
```bash
133+
docker compose exec proxy psql postgres://cipherstash:3ncryp7@localhost:6432/cipherstash
134+
```
135+
136+
Update the data we inserted in [Step 1](#getting-started-step-1), and read it back:
137+
138+
```sql
139+
UPDATE users SET encrypted_dob = '1978-02-01' WHERE encrypted_email = 'alice@cipherstash.com';
140+
141+
SELECT encrypted_dob FROM users WHERE encrypted_email = 'alice@cipherstash.com';
142+
```
143+
144+
In the `UPDATE` statement, the `=` comparison operation in the `WHERE` clause is evaluated against **encrypted** data.
145+
In the `SELECT` statement, the `encrypted_email` value is transparently encrypted by Proxy, and compared in the database against the stored encrypted email value.
146+
In the `SELECT` statement, the `SELECT` returns `1978-02-01`.
147+
148+
Back on the `psql` session connected directly to the database, verify the data is encrypted:
149+
150+
```sql
151+
SELECT encrypted_email, encrypted_dob, encrypted_salary FROM users;
152+
```
153+
154+
This `SELECT` shows the raw encrypted data — no plaintext to see.
155+
156+
### Step 3: Search encrypted data with a `WHERE` clause <a id='getting-started-step-3'></a>
157+
158+
In your `psql` connection to Proxy:
159+
160+
```bash
161+
docker compose exec proxy psql postgres://cipherstash:3ncryp7@localhost:6432/cipherstash
162+
```
163+
164+
Insert more records via Proxy, and search by salary:
165+
166+
```sql
167+
INSERT INTO users (encrypted_email, encrypted_dob, encrypted_salary) VALUES ('bob@cipherstash.com', '1991-03-06', '10');
168+
INSERT INTO users (encrypted_email, encrypted_dob, encrypted_salary) VALUES ('carol@cipherstash.com', '2005-12-30', '1000');
169+
170+
SELECT encrypted_email, encrypted_dob, encrypted_salary FROM users WHERE encrypted_salary <= 100;
171+
```
172+
173+
In the `INSERT` statement, the salary value is transparently encrypted by Proxy, and stored in the database in encrypted form.
174+
In the `SELECT` statement, the `encrypted_salary` value is transparently encrypted and compared in the database against the stored encrypted salary value.
175+
In the `SELECT` statement, the `<=` comparison operation in the `WHERE` clause is evaluated against **encrypted** data.
176+
In the `SELECT` statement, the `SELECT` returns `alice` and `bob`, but not `carol`.
177+
178+
Finally, query `users` by date:
179+
180+
```sql
181+
SELECT encrypted_email, encrypted_dob, encrypted_salary FROM users WHERE encrypted_dob > '2000-01-01' ;
182+
```
183+
184+
The `encrypted_dob` value is transparently encrypted by Proxy, and compared in the database against the stored encrypted date value.
185+
The `>` comparison operation is evaluated against **encrypted** data.
186+
The `SELECT` will only return `carol`.
187+
188+
Back on the `psql` session connected directly to the database, verify the data is encrypted:
189+
190+
```sql
191+
SELECT encrypted_email, encrypted_dob, encrypted_salary FROM users;
192+
```
193+
194+
This `SELECT` shows the raw encrypted data, no plaintext to see.
195+
196+
This demonstrates the power of CipherStash Proxy:
197+
198+
- Completely transparent encryption of sensitive data in PostgreSQL
199+
- All data remains searchable, while being protected with non-deterministic AES-256-GCM encryption
200+
- Zero changes required to your application's database queries
201+
90202
## How-to
91203

92204
This section contains how-to documentation for installing, configuring, and running CipherStash Proxy.

docker-compose.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ services:
4040
- CS_DATABASE__HOST=postgres
4141
- CS_DATABASE__PORT=5432
4242
- CS_PROMETHEUS__ENABLED=${CS_PROMETHEUS__ENABLED:-true}
43-
- CS_DATABASE__INSTALL_EQL=true # install EQL into the PostgreSQL database we start above
43+
- CS_DATABASE__INSTALL_EQL=true # install EQL into the PostgreSQL database
44+
- CS_DATABASE__INSTALL_EXAMPLE_SCHEMA=true # install example schema into the PostgreSQL database
4445
networks:
4546
- cipherstash
4647

docker-entrypoint.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,46 @@ case "${CS_DATABASE__INSTALL_EQL:-}" in
7979
>&2 echo "error: unable to install EQL in target PostgreSQL database!"
8080
exit 2
8181
fi
82+
>&2 echo "Successfully installed EQL in target PostgreSQL database."
8283
;;
8384
*)
8485
>&2 echo "Not installing EQL in target PostgreSQL database."
8586
;;
8687
esac
8788

89+
# Optionally install example schema in the target database
90+
case "${CS_DATABASE__INSTALL_EXAMPLE_SCHEMA:-}" in
91+
"true") ;&
92+
"yes") ;&
93+
"1")
94+
>&2 echo "Applying example schema in target PostgreSQL database..."
95+
96+
SQL_FILENAME="/opt/schema-example.sql"
97+
98+
if [ ! -f "${SQL_FILENAME}" ]; then
99+
>&2 echo "error: unable to find example schema at: ${SQL_FILENAME}"
100+
exit 1
101+
fi
102+
103+
# Wait for postgres to become available
104+
wait_for_postgres_or_exit
105+
106+
# Attempt to install EQL
107+
psql --file=${SQL_FILENAME} --quiet $DATABASE_URL > /dev/null 2>&1
108+
if [ $? != 0 ]; then
109+
>&2 echo "error: unable to apply example schema in target PostgreSQL database!"
110+
exit 2
111+
fi
112+
113+
>&2 echo "Successfully applied example schema in target PostgreSQL database."
114+
>&2 echo "Example tables: users"
115+
;;
116+
*)
117+
>&2 echo "Not installing example schema in target PostgreSQL database."
118+
;;
119+
esac
120+
121+
>&2 echo "Proxy container setup complete!"
122+
>&2 echo "Running CipherStash Proxy..."
123+
88124
exec cipherstash-proxy "$@"
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
TRUNCATE TABLE cs_configuration_v1;
2+
3+
-- Exciting cipherstash table
4+
DROP TABLE IF EXISTS users;
5+
CREATE TABLE users (
6+
id SERIAL PRIMARY KEY,
7+
encrypted_email cs_encrypted_v1,
8+
encrypted_dob cs_encrypted_v1,
9+
encrypted_salary cs_encrypted_v1
10+
);
11+
12+
SELECT cs_add_index_v1(
13+
'users',
14+
'encrypted_email',
15+
'unique',
16+
'text'
17+
);
18+
19+
SELECT cs_add_index_v1(
20+
'users',
21+
'encrypted_email',
22+
'match',
23+
'text'
24+
);
25+
26+
SELECT cs_add_index_v1(
27+
'users',
28+
'encrypted_email',
29+
'ore',
30+
'text'
31+
);
32+
33+
SELECT cs_add_index_v1(
34+
'users',
35+
'encrypted_salary',
36+
'ore',
37+
'int'
38+
);
39+
40+
SELECT cs_add_index_v1(
41+
'users',
42+
'encrypted_dob',
43+
'ore',
44+
'date'
45+
);
46+
47+
SELECT cs_encrypt_v1();
48+
SELECT cs_activate_v1();

proxy.Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
1111

1212
# Copy EQL install scripts
1313
COPY cipherstash-eql.sql /opt/cipherstash-eql.sql
14+
# Copy example schema
15+
COPY docs/getting-started/schema-example.sql /opt/schema-example.sql
1416

1517
# Make the AWS global bundle available for use in the docker-entrypoint.sh script.
1618
ENV CS_DATABASE__AWS_BUNDLE_PATH="./aws-rds-global-bundle.pem"

0 commit comments

Comments
 (0)