Skip to content

Commit 599dd44

Browse files
authored
Merge pull request #300 from authzed/expiring-rels
document expiring relationships
2 parents f7f269b + 1f1a84b commit 599dd44

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import { Callout } from 'nextra/components';
2+
import YouTube from 'react-youtube';
3+
4+
# Expiring Relationships
5+
6+
<Callout type="info">
7+
Expiring Relationships is available from SpiceDB 1.40 onwards.
8+
</Callout>
9+
10+
<Callout type="info">
11+
The clock used to determine if a relationship is expired is that of the underlying SpiceDB datastore.
12+
This gets trickier when using distributed databases like CockroachDB or Spanner, where clocks have an uncertainty range.
13+
When operating your own database, it's key to keep node clocks in sync - we recommend services like [Amazon Time Sync Service](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/set-time.html).
14+
You should evaluate the impact of clock drift in your application.
15+
</Callout>
16+
17+
A common use-case is to model relationships that expire after a certain amount of time.
18+
This is useful to grant temporary access to a resource.
19+
20+
Until now, caveats was the recommended way to support time-bound permissions, but that has some limitations:
21+
22+
- It requires clients to provide the `now` timestamp.
23+
This is additional complexity for clients.
24+
- Expired caveats are not automatically garbage collected.
25+
This can lead to a large number of caveats in the system and increasing cost for loading those into the runtime and evaluating them.
26+
27+
SpiceDB supports expiring relationships, which lets users define relationships that expire at a given point in time.
28+
29+
## Schema Use
30+
31+
Expiring relationships follow a similar use to caveated subject types.
32+
The novelty here is that, in order to disambiguate between a caveat named `expiration` and the native `expiration` feature,
33+
users would need to add a `use` clause to the schema definition to enable the feature.
34+
35+
```zed
36+
use expiration
37+
38+
definition folder {}
39+
40+
definition resource {
41+
relation folder: folder with expiration
42+
}
43+
```
44+
45+
## API Use
46+
47+
Expiration of a relationship is [on a per-relationship basis](https://buf.build/authzed/api/docs/63b8911ef2871c56e5048d1f40a8473f98457ca9:authzed.api.v1#authzed.api.v1.Relationship)
48+
at write time, using `WriteRelationships` or `BulkImportRelationships` APIs.
49+
The expiration is denoted as part of the `OptionalExpiresAt` field in the relationship.
50+
51+
```textproto
52+
WriteRelationshipsRequest {
53+
Updates: [
54+
RelationshipUpdate{
55+
Operation: CREATE
56+
Relationship: {
57+
Resource: {
58+
ObjectType: "resource",
59+
ObjectId: "someresource",
60+
},
61+
Relation: "viewer",
62+
Subject: {
63+
ObjectType: "user",
64+
ObjectId: "sarah",
65+
},
66+
OptionalExpiresAt: "2022-12-31T23:59:59Z"
67+
}
68+
}
69+
]
70+
}
71+
```
72+
73+
## Garbage Collection
74+
75+
Reclaiming expiring relationships is governed by the same mechanism (and flags) as the deletion of the history of
76+
relationship changes that powers SpiceDB's own MVCC (Multi-Version Concurrency Control), and heavily depends on
77+
the datastore chosen.
78+
79+
- Datastores like Spanner and CockroachDB have built-in support for expiring SQL rows, so Garbage Collection is done by the database itself.
80+
In both cases, expired relationships will be reclaimed after 24 hours, and that can't be changed without directly manipulating the SQL schema.
81+
- Datastores like Postgres and MySQL support it using the same GC job that reclaims old relationship versions, which runs every 5 minutes.
82+
Unlike Spanner and CockroachDB, you can govern the GC window with the corresponding flags.
83+
Relationships will be reclaimed after 24 hours by default.
84+
85+
<Callout type="info">
86+
GC Window should be adjusted based on the needs of the application. How far does you application need to go back in time?
87+
If this is a common use-case, we recommend drastrically reducing the GC window (e.g. 1h, or 30 minutes).
88+
This means SpiceDB will have to evaluate less data when serving authorization checks, which can improve performance
89+
drastically in large-scale deployments.
90+
</Callout>
91+
92+
## Migrating Off Expirationg With Caveats
93+
94+
If you implemented expiration using caveats, this section describes the process to migrate to the new expiration feature.
95+
96+
1. Rename your caveat if you had named it `expiration`
97+
2. Add the new subject type to your relation, and add also a combination where both are used:
98+
99+
```zed
100+
caveat ttl(timeout duration, now string, timeout_creation_timestamp string) {
101+
timestamp(now) - timestamp(timeout_creation_timestamp) < timeout
102+
}
103+
104+
definition folder {}
105+
106+
definition resource {
107+
relation folder: folder with ttl
108+
}
109+
```
110+
111+
Becomes:
112+
113+
```zed
114+
use expiration
115+
116+
caveat ttl(timeout duration, now string, timeout_creation_timestamp string) {
117+
timestamp(now) - timestamp(timeout_creation_timestamp) < timeout
118+
}
119+
120+
definition folder {}
121+
122+
definition resource {
123+
relation folder: folder with ttl | folder with expiration | folder with ttl and expiration
124+
}
125+
```
126+
127+
3. Migrate all relationships to use both the caveat and the new expiration.
128+
This is needed because only one relationship is allowed for a combination of resource/permission/subject.
129+
4. Validate that the new expiration feature works as expected by not providing the needed context for the evaluation
130+
of the `ttl` caveat.
131+
5. Once validated, migrate completely to the new expiration feature by writting all relationships with only expiration
132+
and without caveat.
133+
6. Drop the caveat from your schema once migration is completed
134+
135+
```zed
136+
use expiration
137+
138+
definition folder {}
139+
140+
definition resource {
141+
relation folder: folder with expiration
142+
}
143+
```

0 commit comments

Comments
 (0)