Skip to content

Commit f052315

Browse files
authored
fix: improve schemas and relationships docs (#407)
1 parent b23de9c commit f052315

File tree

6 files changed

+226
-197
lines changed

6 files changed

+226
-197
lines changed

pages/spicedb/concepts/_meta.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"zanzibar": "Google Zanzibar",
3-
"schema": "Schema Language",
3+
"schema": "Schema Language Reference",
44
"relationships": "Writing Relationships",
55
"caveats": "Writing Relationships with Caveats",
66
"expiring-relationships": "Writing Relationships that Expire",

pages/spicedb/concepts/caveats.mdx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ import { Callout } from 'nextra/components'
22

33
# Caveats
44

5-
Caveats are a feature within SpiceDB that allows for relationships to be defined conditionally: the relationship will only be considered present if the caveat expression evaluates to true.
5+
Caveats are expressions that can return true or false, and they can be attached (by name) to relationships.
6+
7+
They allow relationships to be defined conditionally: when executing permission checks (e.g. [CheckPermission]), the caveated relationship will only be considered present if the caveat expression evaluates to true at the time you run the `CheckPermission`.
8+
9+
[CheckPermission]: https://buf.build/authzed/api/docs/main:authzed.api.v1#authzed.api.v1.PermissionsService.CheckPermission
610

711
Caveats allow for an elegant way to model dynamic policies and ABAC-style (Attribute Based Access Control) decisions while still providing scalability and performance guarantees.
812

913
## Defining Caveats
1014

11-
Caveats are named expressions that are defined in schema alongside definitions for object types.
15+
Caveats are named expressions that are defined in the [schema](./schema) alongside definitions for object types.
1216
A caveat definition includes a name, one or more well-typed parameters, and a [CEL expression] returning a boolean value.
1317

1418
[CEL expression]: https://github.com/google/cel-spec

pages/spicedb/concepts/relationships.mdx

Lines changed: 76 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,75 @@ import { Callout } from 'nextra/components'
22

33
# Relationships
44

5-
Relationships bind together two Objects (a Subject and a Resource) via a Relation.
6-
The concept behind ReBAC authorization systems is that by following a chain of relationships, one can determine access.
7-
8-
In SpiceDB, a functioning Permissions System is the combination of [Schema], which defines the structure of data, and Relationships which are the data.
5+
In SpiceDB, a functioning Permissions System is the combination of [Schema], which defines the structure of data, and Relationships, which are the data.
96

107
[schema]: ./schema
118

129
## Understanding Relationships
1310

14-
At its core, authorization logic fundamentally reduces to asking a single question:
11+
Let's start with a simple schema that models a document sharing system:
1512

16-
> Is this actor allowed to perform this action on this resource?
13+
```zed
14+
definition user {}
1715
18-
This question can be broken down into core components:
16+
definition team {
17+
relation member: user
18+
}
1919
20-
```
21-
Is this actor allowed to perform this action on this resource?
22-
/¯¯¯¯¯¯¯/ /¯¯¯¯¯¯¯¯¯/ /¯¯¯¯¯¯¯¯¯¯¯/
23-
object permission or object
24-
(subject) relation (resource)
20+
definition document {
21+
# both specific users and all members of specific teams can edit the document
22+
relation editor: user | team#member
23+
}
2524
```
2625

27-
In SpiceDB parlance, _this actor_ and _this resource_ are both [Objects] and _this action_ is a [Permission] or [Relation] (consider them equivalant for now).
28-
By focusing solely on these components of the question, it becomes clear that this is the same structure as a Relationship: two Objects and a Relation.
26+
This schema defines three types of [Objects]: `user`, `team` and `document`. The `document` type has one **relation** defined on it: `editor`.
2927

30-
The power of ReBAC comes from transforming this basic question into another one:
28+
A **relation** is like a class definition in Object-Oriented programming or a type in a strongly-typed language: it represents a possible type of connection defined in your schema. For example: "documents have editors".
3129

32-
> Does there exist a chain of relationships starting at this resource through this relation that ultimately reaches this subject?
30+
A **relationship** is a specific instance of a relation - it's the actual data. For example: "user `emilia` is an editor of document `readme`"
3331

34-
This new question is one of [graph reachability].
35-
General purpose graph databases optimize for a couple different types of graph traversals; usually [breadth-first search] and [depth-first search], but ReBAC systems are optimized for scalably and efficiently computing reachability along with all of the assumptions that come with the domain of authorization.
32+
### Relationship Syntax
3633

37-
The syntax used for relationships in the [paper that popularized ReBAC](./zanzibar) is as follows:
34+
The syntax used for relationships in the [paper that popularized ReBAC](./zanzibar) and that we use throughout this website is:
3835

3936
```
4037
document:readme#editor@user:emilia
4138
```
4239

43-
Here it is with labels explaining each section around the delimiters:
40+
Let's break this down:
4441

4542
```
4643
resource subject
4744
ID type
4845
\ˍˍˍˍˍ\ \ˍˍ\
4946
document:readme#editor@user:emilia
5047
/¯¯¯¯¯¯¯/ /¯¯¯¯¯/ /¯¯¯¯¯/
51-
resource permission subject
52-
type or relation ID
48+
resource relation subject
49+
type ID
50+
```
51+
52+
This relationship can be read as: "user `emilia` is an `editor` of document `readme`". Note how this is connecting two specific objects.
53+
54+
We can also write relationships that link one object to a set of objects.
55+
56+
```
57+
document:readme#editor@team:engineering#member
58+
```
59+
60+
Let's break this down:
61+
62+
```
63+
resource subject
64+
ID type
65+
\ˍˍˍˍˍ\ \ˍˍ\
66+
document:readme#editor@team:engineering#member
67+
/¯¯¯¯¯¯¯/ /¯¯¯¯¯/ /¯¯¯¯¯¯¯¯¯¯//¯¯¯¯¯/
68+
resource relation subject subject
69+
type ID relation
5370
```
5471

72+
This relationship can be read as: "every object that has the `member` relation to `team:engineering` is an `editor` of document `readme`".
73+
5574
<Callout type="info">
5675
In a real system, Object IDs are most likely a computer-friendly string than something human readable.
5776
Many use-cases use UUIDs or unsigned integers representing the primary key from that data's canonical datastore.
@@ -61,11 +80,45 @@ resource permission subject
6180
Regardless of their representation, Object IDs must be **unique and stable** within the set of IDs for an Object Type.
6281
</Callout>
6382

64-
Relationships are powerful because of their duality: they are both the question and, when written in aggregate, the answer.
83+
### Graph traversals
84+
85+
At its core, authorization logic fundamentally reduces to asking:
86+
87+
> Is this actor allowed to perform this action on this resource?
88+
89+
For example: "Is user `emilia` allowed to `edit` document `readme`?"
90+
91+
If you had these relationships written in SpiceDB:
92+
93+
- `document:readme#editor@user:emilia`
94+
95+
Then the answer is trivial: yes, `emilia` can edit the document.
96+
97+
If, instead, you had these relationships written in SpiceDB:
98+
99+
- `team:engineering#member@user:emilia` - emilia is on the engineering team
100+
- `document:readme#editor@team:engineering#member` - every member on the engineering team can edit the readme
101+
102+
When checking "Can user `emilia` edit document `readme`?", SpiceDB:
103+
104+
1. Starts at `document:readme#editor`
105+
2. Follows the `editor` relation to find `team:engineering#member`
106+
3. Follows the `member` relation to find `user:emilia`
107+
108+
[//]: # (TODO add drawing)
109+
110+
Note how we followed a chain of relationships to answer the question. Or, put differently, we traversed a [graph].
111+
112+
The real power of ReBAC comes from transforming authorization questions into [graph reachability] problems, and then answering them efficiently:
113+
114+
> Is there a chain of **relationships** starting at this resource and relation that ultimately reaches this subject?
115+
116+
This is what makes relationships powerful: they are both **the question you ask** ("does this relationship path exist?") and, when you write many of them together, **they form the answer** (by creating paths through the graph that SpiceDB can traverse).
65117

66118
[Objects]: ./schema#object-type-definitions
67119
[Permission]: ./schema#permissions
68120
[Relation]: ./schema#relations
121+
[graph]: https://en.wikipedia.org/wiki/Graph_(abstract_data_type)
69122
[graph reachability]: https://en.wikipedia.org/wiki/Reachability
70123
[breadth-first search]: https://en.wikipedia.org/wiki/Breadth-first_search
71124
[depth-first search]: https://en.wikipedia.org/wiki/Depth-first_search

0 commit comments

Comments
 (0)