Skip to content

Commit c0cf180

Browse files
authored
Merge pull request #155 from cipherstash/nested-encryption
feat(protect): add support for deeply nested protect schemas
2 parents 94660c6 + cccd751 commit c0cf180

File tree

11 files changed

+1727
-66
lines changed

11 files changed

+1727
-66
lines changed

.changeset/smart-worlds-wait.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cipherstash/protect": minor
3+
---
4+
5+
Added support for deeply nested protect schemas to support more complex model objects.

docs/reference/schema.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Protect.js lets you define a schema in TypeScript with properties that map to yo
88
- [Understanding schema files](#understanding-schema-files)
99
- [Defining your schema](#defining-your-schema)
1010
- [Searchable encryption](#searchable-encryption)
11+
- [Nested objects](#nested-objects)
1112
- [Available index options](#available-index-options)
1213
- [Initializing the Protect client](#initializing-the-protect-client)
1314

@@ -75,6 +76,45 @@ export const protectedUsers = csTable("users", {
7576
});
7677
```
7778

79+
### Nested objects
80+
81+
Protect.js supports nested objects in your schema, allowing you to encrypt **but not search on** nested properties. You can define nested objects up to 3 levels deep.
82+
This is useful for data stores that have less structured data, like NoSQL databases.
83+
84+
You can define nested objects by using the `csValue` function to define a value in a nested object. The value naming convention of the `csValue` function is a dot-separated string of the nested object path, e.g. `profile.name` or `profile.address.street`.
85+
86+
> [!NOTE]
87+
> Using nested objects is not recommended for SQL databases, as it will not be searchable.
88+
> You should either use a JSON data type and encrypt the entire object, or use a separate column for each nested property.
89+
90+
```ts
91+
import { csTable, csColumn, csValue } from "@cipherstash/protect";
92+
93+
export const protectedUsers = csTable("users", {
94+
email: csColumn("email").freeTextSearch().equality().orderAndRange(),
95+
profile: {
96+
name: csValue("profile.name"),
97+
address: {
98+
street: csValue("profile.address.street"),
99+
location: {
100+
coordinates: csValue("profile.address.location.coordinates"),
101+
},
102+
},
103+
},
104+
});
105+
```
106+
107+
When working with nested objects:
108+
- Searchable encryption is not supported on nested objects
109+
- Each level can have its own encrypted fields
110+
- The maximum nesting depth is 3 levels
111+
- Null and undefined values are supported at any level
112+
- Optional nested objects are supported
113+
114+
> [!WARNING]
115+
> TODO: The schema builder does not validate the values you supply to the `csValue` or `csColumn` functions.
116+
> These values are meant to be unique, and and cause unexpected behavior if they are not defined correctly.
117+
78118
## Available index options
79119

80120
The following index options are available for your schema:

0 commit comments

Comments
 (0)