You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -583,7 +583,7 @@ CREATE TABLE users (
583
583
> The `eql_v2_encrypted` type is a [composite type](https://www.postgresql.org/docs/current/rowtypes.html) and each ORM/client has a different way of handling inserts and selects.
584
584
> We've documented how to handle inserts and selects for the different ORMs/clients in the [docs](./docs/reference/working-with-composite-types.md).
585
585
586
-
Read more about [how to search encrypted data](./docs/how-to/searchable-encryption.md) in the docs.
586
+
Read more about [how to search encrypted data](./docs/reference/searchable-encryption.md) in the docs.
-[Using Raw PostgreSQL Client (pg)](#using-raw-postgresql-client-pg)
16
+
-[Using Supabase SDK](#using-supabase-sdk)
17
+
-[Best practices](#best-practices)
18
+
-[Common use cases](#common-use-cases)
9
19
10
-
## Before you start
20
+
## Prerequisites
11
21
12
-
You will have needed to [define your schema and initialized the protect client](../../README.md#defining-your-schema), and have [installed the EQL custom types and functions](../../README.md#searchable-encryption-in-postgresql).
22
+
Before you can use searchable encryption with PostgreSQL, you need to:
13
23
14
-
The below examples assume you have a schema defined:
24
+
1. Install the [EQL custom types and functions](https://github.com/cipherstash/encrypt-query-language?tab=readme-ov-file#installation)
25
+
2. Set up your Protect.js schema with the appropriate search capabilities
> The formal EQL repo documentation is heavily focused on the underlying custom function implementation.
29
+
> It also has a bias towards the [CipherStash Proxy](https://github.com/cipherstash/proxy) product, so this guide is the best place to get started when using Protect.js.
EQL (Encrypt Query Language) is a set of PostgreSQL extensions that enable searching and sorting on encrypted data. It provides:
34
+
35
+
- Custom data types for storing encrypted data
36
+
- Functions for comparing and searching encrypted values
37
+
- Support for range queries and sorting on encrypted data
38
+
39
+
When you install EQL, it adds these capabilities to your PostgreSQL database, allowing Protect.js to perform operations on encrypted data without decrypting it first.
40
+
41
+
> [!IMPORTANT]
42
+
> Any column that is encrypted with EQL must be of type `eql_v2_encrypted` which is included in the EQL extension.
43
+
44
+
## Setting up your schema
45
+
46
+
Define your Protect.js schema using `csTable` and `csColumn` to specify how each field should be encrypted and searched:
.orderAndRange(), // Enables sorting and range queries
56
+
phone: csColumn('phone_encrypted')
57
+
.equality(), // Only exact matching
58
+
age: csColumn('age_encrypted')
59
+
.orderAndRange() // Only sorting and range queries
60
+
})
61
+
```
62
+
63
+
## The `createSearchTerms` function
64
+
65
+
The `createSearchTerms` function is used to create search terms used in the SQL query.
66
+
67
+
The function takes an array of objects, each with the following properties:
68
+
69
+
| Property | Description |
70
+
|----------|-------------|
71
+
|`value`| The value to search for |
72
+
|`column`| The column to search in |
73
+
|`table`| The table to search in |
74
+
|`returnType`| The type of return value to expect from the SQL query. Required for PostgreSQL composite types. |
75
+
76
+
**Return types:**
77
+
78
+
-`eql` (default) - EQL encrypted payload
79
+
-`composite-literal` - EQL encrypted payload wrapped in a composite literal
80
+
-`escaped-composite-literal` - EQL encrypted payload wrapped in an escaped composite literal
81
+
82
+
Example:
83
+
84
+
```typescript
85
+
const term =awaitprotectClient.createSearchTerms([{
86
+
value: 'user@example.com',
87
+
column: schema.email,
88
+
table: schema,
89
+
returnType: 'composite-literal'
90
+
}, {
91
+
value: '18',
92
+
column: schema.age,
93
+
table: schema,
94
+
returnType: 'composite-literal'
95
+
}])
96
+
97
+
if (term.failure) {
98
+
// Handle the error
99
+
}
100
+
101
+
console.log(term.data) // array of search terms
102
+
```
103
+
104
+
> [!NOTE]
105
+
> As a developer, you must track the index of the search term in the array when using the `createSearchTerms` function.
106
+
107
+
## Search capabilities
108
+
109
+
### Exact matching
110
+
111
+
Use `.equality()` when you need to find exact matches:
112
+
113
+
```typescript
114
+
// Find user with specific email
115
+
const term =awaitprotectClient.createSearchTerms([{
116
+
value: 'user@example.com',
117
+
column: schema.email,
118
+
table: schema,
119
+
returnType: 'composite-literal'// Required for PostgreSQL composite types
120
+
}])
121
+
122
+
if (term.failure) {
123
+
// Handle the error
124
+
}
125
+
126
+
// SQL query
127
+
const result =awaitclient.query(
128
+
'SELECT * FROM users WHERE email_encrypted = $1',
129
+
[term.data[0]]
130
+
)
131
+
```
132
+
133
+
### Free text search
134
+
135
+
Use `.freeTextSearch()` for text-based searches:
136
+
137
+
```typescript
138
+
// Search for users with emails containing "example"
139
+
const term =awaitprotectClient.createSearchTerms([{
140
+
value: 'example',
141
+
column: schema.email,
142
+
table: schema,
143
+
returnType: 'composite-literal'
144
+
}])
145
+
146
+
if (term.failure) {
147
+
// Handle the error
148
+
}
149
+
150
+
// SQL query
151
+
const result =awaitclient.query(
152
+
'SELECT * FROM users WHERE email_encrypted LIKE $1',
153
+
[term.data[0]]
154
+
)
155
+
```
156
+
157
+
### Sorting and range queries
158
+
159
+
Use `.orderAndRange()` for sorting and range operations:
160
+
161
+
> [!NOTE]
162
+
> When using ORDER BY with encrypted columns, you need to use the EQL v2 functions if your PostgreSQL database doesn't support EQL Operator families. For databases that support EQL Operator families, you can use ORDER BY directly with encrypted column names.
163
+
164
+
```typescript
165
+
// Get users sorted by age
166
+
const result =awaitclient.query(
167
+
'SELECT * FROM users ORDER BY eql_v2.ore_block_u64_8_256(age_encrypted) ASC'
Copy file name to clipboardExpand all lines: packages/protect/README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -583,7 +583,7 @@ CREATE TABLE users (
583
583
> The `eql_v2_encrypted` type is a [composite type](https://www.postgresql.org/docs/current/rowtypes.html) and each ORM/client has a different way of handling inserts and selects.
584
584
> We've documented how to handle inserts and selects for the different ORMs/clients in the [docs](./docs/reference/working-with-composite-types.md).
585
585
586
-
Read more about [how to search encrypted data](./docs/how-to/searchable-encryption.md) in the docs.
586
+
Read more about [how to search encrypted data](./docs/reference/searchable-encryption.md) in the docs.
0 commit comments