Skip to content

Commit f7f269b

Browse files
authored
Merge pull request #299 from authzed/use-of-caveats-in-playground
better describe use of caveats in playground/zed
2 parents c8cd78e + f2935e5 commit f7f269b

File tree

3 files changed

+122
-7
lines changed

3 files changed

+122
-7
lines changed

pages/spicedb/concepts/caveats.mdx

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,21 +117,31 @@ A few important notes:
117117
Otherwise, the values in the `Relationship` take precedence over those in the `CheckPermissionRequest`.
118118
- Context of a caveat provided in `Relationship` is stored alongside the relationship and is provided to the caveat expression at runtime.
119119
This allows for **partial** binding of data at write time.
120-
- The Context is a `structpb`, which is defined by Google and represents JSON-like data: [https://pkg.go.dev/google.golang.org/protobuf/types/known/structpb](https://pkg.go.dev/google.golang.org/protobuf/types/known/structpb)
120+
- The Context is a `structpb`, which is defined by Google [and represents JSON-like data](https://pkg.go.dev/google.golang.org/protobuf/types/known/structpb).
121121
- To send 64-bit integers, encode them as strings.
122122
- A relationship cannot be duplicated, with or without a caveat, e.g. two relationships that differ only on their use of a caveat cannot both exist.
123123
- When deleting a relationship, a caveat does not need to be specified; the matching relationship will be deleted if present.
124124

125-
## Issuing Checks
125+
## Providing Caveat Context via the API
126+
127+
### `CheckPermission`
126128

127129
When issuing a [CheckPermission request][check-req], additional caveat context can be specified to represent the known context at the time of the check:
128130

129131
```textproto
130132
CheckPermissionRequest {
131-
Resource: …,
132-
Permission: …,
133-
Subject: …,
134-
Context: { "user_ip": "1.2.3.4" }
133+
resource: {
134+
object_type: "book",
135+
object_id: "specificbook",
136+
},
137+
permission: "view",
138+
subject: {
139+
object: {
140+
object_type: "user",
141+
object_id: "specificuser",
142+
},
143+
},
144+
context: { "user_ip": "1.2.3.4" }
135145
}
136146
```
137147

@@ -147,10 +157,56 @@ In the case of `PERMISSIONSHIP_CONDITIONAL_PERMISSION`, SpiceDB will also return
147157
[states]: https://buf.build/authzed/api/docs/main:authzed.api.v1#authzed.api.v1.CheckPermissionResponse.Permissionship
148158
[check-resp]: https://buf.build/authzed/api/docs/main:authzed.api.v1#authzed.api.v1.CheckPermissionResponse
149159

150-
## LookupResources and LookupSubjects
160+
## `LookupResources` and `LookupSubjects`
151161

152162
Similarly to **CheckPermission**, both **LookupResources** and **LookupSubjects** can be provided with additional context and will return one of the two permission states for each of the results found (either has permission or conditionally has permission).
153163

164+
```textproto
165+
LookupResourcesRequest {
166+
resource_object_type: "book",
167+
permission: "view",
168+
subject: {
169+
object: {
170+
object_type: "user",
171+
object_id: "specificuser",
172+
},
173+
},
174+
context: { "user_ip": "1.2.3.4" }
175+
}
176+
```
177+
178+
### Providing Caveat Context with `zed CLI
179+
180+
When using `zed` command-line tool to interact with SpiceDB, the context can be provided using the `--caveat-context` flag.
181+
The caveat context should be a JSON representation that matches the types defined in the schema.
182+
For example, with the following caveat:
183+
184+
```zed
185+
caveat first_caveat(first_parameter int, second_parameter string) {
186+
first_parameter == 42 && second_parameter == "hello world"
187+
}
188+
```
189+
190+
We would need to forward a JSON object like:
191+
192+
```json
193+
{
194+
"first_parameter": 42,
195+
"second_parameter": "hello world"
196+
}
197+
```
198+
199+
The full command would look like:
200+
201+
```shell
202+
zed check -r resource:specificresource#view -p view -s user:specificuser --caveat-context '{"first_parameter": 42, "second_parameter": "hello world"}'
203+
```
204+
205+
<Callout type="info">
206+
Please note the use of single quotes to escape the characters in the JSON representation of the context.
207+
You don't need character escaping when providing context using zed in the Authzed Playground.
208+
</Callout>
209+
154210
## Full Example
155211

156212
A full example of a schema with caveats can be found below, which allows users to `view` a resource if they are directly a `viewer` or they are a`viewer` within the correct IP CIDR range:

pages/spicedb/modeling/validation-testing-debugging.mdx

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,29 @@ assertTrue:
5757
assertFalse: []
5858
```
5959
60+
#### Caveat Context In Assertions
61+
62+
<Callout type="info">
63+
In order to escape JSON representation of the caveat context in an assertion you should use single-quotes
64+
</Callout>
65+
66+
You can provide caveat context as part of an assertion:
67+
68+
```yaml
69+
assertTrue:
70+
- 'document:validation-testing-debugging#reader@user:you with {"somecondition": 42, "anothercondition": "hello world"}'
71+
assertFalse: []
72+
```
73+
74+
You can also assert that a caveat context is required for a particular expression using `assertCaveated`:
75+
76+
```yaml
77+
assertTrue: []
78+
assertCaveated:
79+
- "document:validation-testing-debugging#reader@user:you"
80+
assertFalse: []
81+
```
82+
6083
### Check Watches
6184

6285
Check Watches are type of assertion that updates in real-time with changes in the Playground.
@@ -67,6 +90,15 @@ Below is an example of configuring a Check Watch:
6790
<br />
6891
<YouTube videoId="UmvGPU8iQ-0" />
6992

93+
Watches can show any of the following states:
94+
95+
- ✅ Permission Allowed
96+
- ❔ Permission Caveated
97+
- ❌ Permission Denied
98+
- ⚠️ Invalid Check
99+
100+
![check-watches](/images/check-watches.png)
101+
70102
### Expected Relations
71103

72104
Expected Relations are a type of assertion that can be used to enumerate access to a specific relation.
@@ -88,6 +120,33 @@ project:docs#admin:
88120
- "[user:rauchg] is <platform:vercel#admin>"
89121
```
90122

123+
### Caveats in Expected Relations
124+
125+
When caveats are involved, and due to the unbounded nature of it, the Playground will focus on enumerating
126+
expected relations with "maybe" semantics.
127+
You can't specify an expected relation with a specific caveat context, because the Playground supports inferring those for you,
128+
and that would lead potentially to an infinite number of possible caveat context values.
129+
130+
What you'll see is an expected relation with the caveat context denoted as `[...]` right after the resource.
131+
This reads as `user:rauchg may have admin permission over platform vercel`.
132+
133+
```yaml
134+
project:docs#admin:
135+
- "[user:rauchg[...]] is <platform:vercel#admin>"
136+
```
137+
138+
### Exceptions in Expected Relations
139+
140+
There are also scenarios where an expected relation is described with an exception, which indicates that a permission
141+
holds for a specific resource and subject pair, but with a potential exception.
142+
143+
The following example reads like: `user:rauchg has admin permission over platform vercel, unless user:rauchg is banned`.
144+
145+
```yaml
146+
project:docs#admin:
147+
- "[user:rauchg[...]] is <platform:vercel#admin>/<platform:vercel#banned>"
148+
```
149+
91150
## Check Tracing
92151

93152
SpiceDB supports tracing of check requests to view the path(s) taken to compute the result, as well as timing information.

public/images/check-watches.png

58.8 KB
Loading

0 commit comments

Comments
 (0)