Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

better describe use of caveats in playground/zed #299

Merged
merged 1 commit into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 63 additions & 7 deletions pages/spicedb/concepts/caveats.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -117,21 +117,31 @@ A few important notes:
Otherwise, the values in the `Relationship` take precedence over those in the `CheckPermissionRequest`.
- Context of a caveat provided in `Relationship` is stored alongside the relationship and is provided to the caveat expression at runtime.
This allows for **partial** binding of data at write time.
- 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)
- 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).
- To send 64-bit integers, encode them as strings.
- 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.
- When deleting a relationship, a caveat does not need to be specified; the matching relationship will be deleted if present.

## Issuing Checks
## Providing Caveat Context via the API

### `CheckPermission`

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

```textproto
CheckPermissionRequest {
Resource: …,
Permission: …,
Subject: …,
Context: { "user_ip": "1.2.3.4" }
resource: {
object_type: "book",
object_id: "specificbook",
},
permission: "view",
subject: {
object: {
object_type: "user",
object_id: "specificuser",
},
},
context: { "user_ip": "1.2.3.4" }
}
```

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

## LookupResources and LookupSubjects
## `LookupResources` and `LookupSubjects`

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).

```textproto
LookupResourcesRequest {
resource_object_type: "book",
permission: "view",
subject: {
object: {
object_type: "user",
object_id: "specificuser",
},
},
context: { "user_ip": "1.2.3.4" }
}
```

### Providing Caveat Context with `zed CLI

When using `zed` command-line tool to interact with SpiceDB, the context can be provided using the `--caveat-context` flag.
The caveat context should be a JSON representation that matches the types defined in the schema.
For example, with the following caveat:

```zed
caveat first_caveat(first_parameter int, second_parameter string) {
first_parameter == 42 && second_parameter == "hello world"
}
```

We would need to forward a JSON object like:

```json
{
"first_parameter": 42,
"second_parameter": "hello world"
}
```

The full command would look like:

```shell
zed check -r resource:specificresource#view -p view -s user:specificuser --caveat-context '{"first_parameter": 42, "second_parameter": "hello world"}'
```

<Callout type="info">
Please note the use of single quotes to escape the characters in the JSON representation of the context.
You don't need character escaping when providing context using zed in the Authzed Playground.
</Callout>

## Full Example

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:
Expand Down
59 changes: 59 additions & 0 deletions pages/spicedb/modeling/validation-testing-debugging.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,29 @@ assertTrue:
assertFalse: []
```

#### Caveat Context In Assertions

<Callout type="info">
In order to escape JSON representation of the caveat context in an assertion you should use single-quotes
</Callout>

You can provide caveat context as part of an assertion:

```yaml
assertTrue:
- 'document:validation-testing-debugging#reader@user:you with {"somecondition": 42, "anothercondition": "hello world"}'
assertFalse: []
```

You can also assert that a caveat context is required for a particular expression using `assertCaveated`:

```yaml
assertTrue: []
assertCaveated:
- "document:validation-testing-debugging#reader@user:you"
assertFalse: []
```

### Check Watches

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

Watches can show any of the following states:

- ✅ Permission Allowed
- ❔ Permission Caveated
- ❌ Permission Denied
- ⚠️ Invalid Check

![check-watches](/images/check-watches.png)

### Expected Relations

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

### Caveats in Expected Relations

When caveats are involved, and due to the unbounded nature of it, the Playground will focus on enumerating
expected relations with "maybe" semantics.
You can't specify an expected relation with a specific caveat context, because the Playground supports inferring those for you,
and that would lead potentially to an infinite number of possible caveat context values.

What you'll see is an expected relation with the caveat context denoted as `[...]` right after the resource.
This reads as `user:rauchg may have admin permission over platform vercel`.

```yaml
project:docs#admin:
- "[user:rauchg[...]] is <platform:vercel#admin>"
```

### Exceptions in Expected Relations

There are also scenarios where an expected relation is described with an exception, which indicates that a permission
holds for a specific resource and subject pair, but with a potential exception.

The following example reads like: `user:rauchg has admin permission over platform vercel, unless user:rauchg is banned`.

```yaml
project:docs#admin:
- "[user:rauchg[...]] is <platform:vercel#admin>/<platform:vercel#banned>"
```

## Check Tracing

SpiceDB supports tracing of check requests to view the path(s) taken to compute the result, as well as timing information.
Expand Down
Binary file added public/images/check-watches.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading