Skip to content
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
45 changes: 25 additions & 20 deletions docs/guides/permissions/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,21 @@ Read the dedicated documents to learn more about [subjects](/keto/concepts/15_su

:::

Examples of relationships are:
Each relationship consists of:

```keto-relationships
users:user1 is in members of groups:group1
members of groups:group1 are readers of files:file1
- **Subject** – The entity that receives the role or permission.
- **Object** – The entity on which the role or permission is granted.
- **Relation** – The relationship between Subject and Object.

Examples:

```keto-natural
User:user1 is in members of Group:group1
admins of Group:group1 are readers of File:file1
```

As you can see, the subject of a relationship can either be a specific subject ID, or subjects defined through an
[indirection](https://en.wikipedia.org/wiki/Indirection) (all members of a certain group). The object is referenced by its ID.
As you can see, the subject of a relationship can either be a specific subject ID (e.g. User:user1), or subjects defined through
an indirection (e.g. all admins of Group:group1). The object is referenced by its ID (e.g. Group:group1, File:file1).

### Checking permissions

Expand All @@ -47,28 +53,28 @@ certain relation to an object, possibly through one or more indirections.

As a very simple example, let's assume the following tuples exist:

```keto-relationships
users:user1 is in members of groups:group1
members of groups:group1 are readers of files:file1
```keto-natural
User:user1 is in members of Group:group1
members of Group:group1 are readers of File:file1
```

Based on these tuples, you can run permission checks:

- Is `user1` a `reader` of `file1`?
- Is `User:user1` a `reader` of `File:file1`?

```keto-relationships
is users:user1 in readers of files:file1? // Yes
```keto-natural
is User:user1 in readers of File:file1? // Yes
```

Yes, because `user1` is in `members` of `groups:group1` and all `members` of `groups:group1` are `readers` of `files:file1`.
Yes, because `user1` is in `members` of `Group:group1` and all `members` of `Group:group1` are `readers` of `File:file1`.

- Is `user2` a member of `group1`?
- Is `User:user2` a member of `Group:group1`?

```keto-relationships
is users:user2 in members of groups:group1? // No
```keto-natural
is User:user2 in members of Group:group1? // No
```

No, because there is no relation between `user2` and `group1`.
No, because there is no relation between `User:user2` and `Group:group1`.

## Example

Expand Down Expand Up @@ -156,7 +162,6 @@ ory create relationships relationships.json

# Output:
# NAMESPACE OBJECT RELATION NAME SUBJECT
# Group developer members patrik
# Group developer members User:Patrik
# Group developer members User:Henning
# Folder keto/ viewers Group:developer#members
Expand All @@ -172,8 +177,8 @@ With the relationships created, try running queries that illustrate use cases:

#### Transitive permissions for objects in the hierarchy

Patrik can view `keto/src/main.go`. This file is in the `keto/src` folder, which is in `keto`. The `keto` directory has the
"developer" group as its "viewers". Patrik is a member of the "developer" group.
Patrik can view `keto/src/main.go`, because this file is in the `keto/src` folder, which is in `keto`. The `keto` directory has
the "developer" group as its "viewers". Patrik is a member of the "developer" group.

```
ory is allowed User:Patrik view File keto/src/main.go
Expand Down
4 changes: 2 additions & 2 deletions docs/keto/concepts/01_relation-tuples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ configured.

You can think of relationships as edges in a graph. For a simple relationship:

```keto-relationships
```keto-natural
User:user1 is in members of Group:group1
User:user2 is in readers of Document:readme.txt
Folder:src is in parents of Document:package.json
Expand All @@ -27,7 +27,7 @@ Folder:src is in parents of Document:package.json

The [Zanzibar paper](https://research.google/pubs/pub48190/) uses the following notation for relationships:

```keto-relation-tuples
```keto-tuples
Group:group1#members@User:user1
```

Expand Down
10 changes: 5 additions & 5 deletions docs/keto/concepts/05_namespaces.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Folder implements Namespace {}
Each namespace holds a set of permissions, which define which relationships are checked. For example, checking a `view` permission
for `User:bob` on an `readme.txt` file in the `Document` namespace requires the following relationship lookups:

```keto-relationships
```keto-natural
is User:bob in viewers of Document:readme.txt // all viewers can view the document
is User:bob in editors of Document:readme.txt // all editors can view the document
is User:bob in owners of Document:readme.txt // all owners can view the document
Expand All @@ -56,8 +56,8 @@ the type they describe. The name should be in [upper camel case](https://wiki.c2
Relationships in a namespace should be named with a plural form word that describes what relation a subject has with an object.
Every relationship should translate to an English sentence, for example:

```keto-relationships
Subject is in members of Object
```keto-natural
<Subject> is in <relation> of <Object>
```

Relationships are like the edges in a graph connecting subjects and objects. These edges are always
Expand All @@ -68,7 +68,7 @@ form.

- Correct naming ✅

```keto-relationships
```keto-natural
User:02a3c847-c903-446a-a34f-dae74b4fab86 is in writers of File:8f427c01-c295-44f3-b43d-49c3a1042f35
User:b8d00059-b803-4123-9d3d-b3613bfe7c1b is in members of Group:43784684-103e-44c0-9d6c-db9fb265f617
File:11488ab9-4ede-479f-add4-f1379da4ae43 is in children of Directory:803a87e9-0da0-486e-bc08-ef559dd8e034
Expand All @@ -77,7 +77,7 @@ form.

- Incorrect naming ❌

```keto-relationships
```keto-natural
// namespace isn't describing homogenous type of objects
User:7a012165-7b21-495b-b84b-cf4e1a21b484 is in members of Tenant1Objects:62237c27-19c3-4bb1-9cbc-a5a67372569b

Expand Down
2 changes: 1 addition & 1 deletion docs/keto/concepts/10_objects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ c4540cf5-6ac4-4007-910b-c5a56aa3d4e6:

Ory Permissions has the following relationships:

```keto-relation-tuples
```keto-tuples
// Members of the "admins" group are allowed to set a value v > 5
values:f832e1e7-3c97-4cb8-8582-979e63ae2f1d#set_value@(groups:admins#member)

Expand Down
5 changes: 2 additions & 3 deletions docs/keto/concepts/15_subjects.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,8 @@ c5b6454f-f79c-4a6d-9e1b-b44e04b56009:

Ory Permissions understands the following relationship:

```keto-relation-tuples
// Allow access to TCP port 22 when the request originates from a specific subnet during office hours
tcp/22#access@c5b6454f-f79c-4a6d-9e1b-b44e04b56009
```keto-natural
UserAttributes:c5b6454f-f79c-4a6d-9e1b-b44e04b56009 is allowed to access TcpPort:22
```

The application must map every incoming request to a subject string that represents the attributes of the request. Ory Permissions
Expand Down
53 changes: 23 additions & 30 deletions docs/keto/concepts/20_graph-of-relations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,24 @@ Edges are directed and represent the relation between an object and subject.

The following example translates a view relationships into a graph of relations.

:::note

This example omits the [namespace](./05_namespaces.mdx) from all data to improve readability. In practice, the namespace always
has to be considered.

:::

```keto-relation-tuples
// user1 has access on dir1
dir1#access@user1
```keto-tuples
// User:1 has access on Dir:1
Dir:1#access@User:1

// This is an empty relation.
dir1#child@(file1#)
Dir:1#child@(File:1#)

// Everyone with access to dir1 has access to file1.
file1#access@(dir1#access)
// Everyone with access to Dir:1 has access to File:1.
File:1#access@(Dir:1#access)

// Direct access on file2 was granted.
file2#access@user1
// Direct access on File:2 was granted.
File:2#access@User:1

// user2 is owner of file2
file2#owner@user2
// User:2 is owner of File:2
File:2#owner@User:2

// Owners of file2 have access to it; possibly defined through subject set rewrites.
file2#access@(file2#owner)
// Owners of File:2 have access to it; possibly defined through subject set rewrites.
File:2#access@(File:2#owner)
```

This is represented by the following graph:
Expand All @@ -65,21 +58,21 @@ Solid edges represent explicitly defined relations, while dotted edges represent
chart={`
graph TD
subgraph obj [Object region]
E[dir1]
A[file1] -->|child| E
G[file2]
E[Dir:1]
A[File:1] -->|child| E
G[File:2]
end
subgraph subjID [Subject ID region]
F([user1])
C([user2])
F([User:1])
C([User:2])
end
A -->|access| B{{dir1#access}}
B -. file1#access .-> F
A -->|access| B{{Dir:1#access}}
B -. File:1#access .-> F
E -->|access| F
G -->|access| F
G -->|owner| C
G -->|access| H{{file2#owner}}
H -. file2#access .-> C
G -->|access| H{{File:2#owner}}
H -. File:2#access .-> C
`}
/>
```
Expand All @@ -95,5 +88,5 @@ Ory Permissions utilizes the following key properties of the graph of relations:

Trying to find a path from an object to a subject will always happen locally. This means that it's only necessary to traverse
the nodes that are successors of the object. In typical setups, this means that only a small fraction of the graph has to be
searched, regardless of the outcome. The intuition here is that the relations of user1's files are irrelevant when checking
access to user2's files.
searched, regardless of the outcome. The intuition here is that the relations of User:1's files are irrelevant when checking
access to User:2's files.
54 changes: 27 additions & 27 deletions docs/keto/examples/olymp-file-sharing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,50 +15,50 @@ defined, where each `owner` of an object also has `access` to that object. All r

:::

Now, the user identified by its unique username `demeter` wants to upload a file containing the most fertile grounds. The file
gets assigned the UUID `ec788a82-a12e-45a4-b906-3e69f78c94e4`. The application adds the following
Now, the user identified by its unique username `Bob` wants to upload a file containing the most fertile grounds. The file gets
assigned the UUID `ec788a82-a12e-45a4-b906-3e69f78c94e4`. The application adds the following
[relationship](../concepts/01_relation-tuples.mdx) to Ory Keto through the
[write-API](../concepts/25_api-overview.mdx#write-apis):

```keto-relation-tuples
ec788a82-a12e-45a4-b906-3e69f78c94e4#owner@demeter
```keto-tuples
File:ec788a82-a12e-45a4-b906-3e69f78c94e4#owner@User:Bob
```

To prepare for an important meeting with the user `athena`, `demeter` wants to share the file with fertile grounds with `athena`
so that they can both read it. Therefore, he opens the "Olymp Library" and is presented with a list of all files he owns. The
application will internally request all [objects](../concepts/10_objects.mdx) (file IDs) with the owner `demeter` by using the
To prepare for an important meeting with the user `Alice`, `Bob` wants to share the file with fertile grounds with `Alice` so that
they can both read it. Therefore, he opens the "Olymp Library" and is presented with a list of all files he owns. The application
will internally request all [objects](../concepts/10_objects.mdx) (file IDs) with the owner `Bob` by using the
[list-API](../concepts/25_api-overview.mdx#list-relationships). The response will contain the object
`ec788a82-a12e-45a4-b906-3e69f78c94e4`, which the application maps to the file in question.

The user `demeter` will then ask the application to share the file with `athena`. The application will translate that request into
a [write-API request](../concepts/25_api-overview.mdx#write-apis) adding the following relationship to Ory Keto:
The user `Bob` will then ask the application to share the file with `Alice`. The application will translate that request into a
[write-API request](../concepts/25_api-overview.mdx#write-apis) adding the following relationship to Ory Keto:

```keto-relation-tuples
ec788a82-a12e-45a4-b906-3e69f78c94e4#access@athena
```keto-tuples
File:ec788a82-a12e-45a4-b906-3e69f78c94e4#access@User:Alice
```

To confirm the successful operation, the application uses Ory Keto's
[expand-API](../concepts/25_api-overview.mdx#expand-subject-sets) to compile a list of everyone who can access the file:

```keto-relation-tuples
```keto-tuples
// The following subject set is expanded by Keto
ec788a82-a12e-45a4-b906-3e69f78c94e4#access
File:ec788a82-a12e-45a4-b906-3e69f78c94e4#access
```

which returns the expansion tree

```
∪ ec788a82-a12e-45a4-b906-3e69f78c94e4#access
├─ ∪ ec788a82-a12e-45a4-b906-3e69f78c94e4#owner
│ ├─ ☘ demeter
├─ ☘ athena
```keto-tuples
File:ec788a82-a12e-45a4-b906-3e69f78c94e4#access
├─ ∪ File:ec788a82-a12e-45a4-b906-3e69f78c94e4#owner
│ ├─ ☘ User:Bob
├─ ☘ User:Alice
```

The "Olymp Library" can then display this information to `demeter`.
The "Olymp Library" can then display this information to `Bob`.

When `athena` wants to get the file containing fertile grounds, the application uses the
[check-API](../concepts/25_api-overview.mdx#check-relationships) to verify that `athena` has access to the file before it returns
the file. This will allow `demeter` to revoke `athena`'s access at any point by deleting the corresponding relationship.
When `Alice` wants to get the file containing fertile grounds, the application uses the
[check-API](../concepts/25_api-overview.mdx#check-relationships) to verify that `Alice` has access to the file before it returns
the file. This will allow `Bob` to revoke `Alice`'s access at any point by deleting the corresponding relationship.

This diagram illustrates the relationships in this example:

Expand All @@ -68,13 +68,13 @@ import Mermaid from "@site/src/theme/Mermaid"
<Mermaid
chart={`
flowchart TD
obj1[files:ec788a82-a12e-45a4-b906-3e69f78c94e4] --- r1((owner))
r1 ---- sub1(["demeter"])
obj1[File:ec788a82-a12e-45a4-b906-3e69f78c94e4] --- r1((owner))
r1 ---- sub1(["User:Bob"])
obj1 --- r2((access))
r1 -.-> r2
r2 --- sub2(["athena"])
style sub1 fill:lightgreen
style sub2 fill:lightgreen
r2 --- sub2(["User:Alice"])
style sub1 fill:green,color:white
style sub2 fill:green,color:white
style r1 fill:darkgreen,color:white
style r2 fill:darkgreen,color:white
`}
Expand Down
24 changes: 12 additions & 12 deletions docs/keto/guides/expand-api-display-who-has-access.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,21 @@ To assist users with managing permissions for their files, the application has t
this example, we assume that the application knows the following files and directories:

```
├─ photos (owner: maureen; shared with laura)
├─ beach.jpg (owner: maureen)
├─ mountains.jpg (owner: laura)
├─ photos (owner: Alice; shared with Bob)
├─ beach.jpg (owner: Alice)
├─ mountains.jpg (owner: Bob)
```

This is represented in Ory Keto by the following [relationships](../concepts/01_relation-tuples.mdx):

```keto-relation-tuples
```keto-tuples
// ownership
directories:/photos#owner@maureen
files:/photos/beach.jpg#owner@maureen
files:/photos/mountains.jpg#owner@laura
directories:/photos#owner@Alice
files:/photos/beach.jpg#owner@Alice
files:/photos/mountains.jpg#owner@Bob

// maureen granted access to /photos to laura
directories:/photos#access@laura
// Alice granted access to /photos to Bob
directories:/photos#access@Bob

// the following tuples are defined implicitly through subject set rewrites (not supported yet)
directories:/photos#access@(directories:/photos#owner)
Expand All @@ -58,8 +58,8 @@ directories:/photos#parent@(files:/photos/beach.jpg#_)
directories:/photos#parent@(files:/photos/mountains.jpg#_)
```

The user `maureen` now wants to manage `access` for the file `/photos/beach.jpg`. Therefore, the application uses the expand-API
to get a tree of everyone who has access to that file.
The user `Alice` now wants to manage `access` for the file `/photos/beach.jpg`. Therefore, the application uses the expand-API to
get a tree of everyone who has access to that file.

:::note

Expand All @@ -68,7 +68,7 @@ TLS.

:::

<CodeTabs sampleId="expand-api-display-access/01-expand-beach" version="master" />
<CodeTabs sampleId="expand-api-display-access/01-expand-beach" version="master" outputExt="json" />

### Maximum tree depth

Expand Down
Loading
Loading