Konubinix' opinionated web of thoughts

Ory Permissions

Fleeting

ory permissions is a part of ory network that provides ory keto.

It claims to implement zanzibar1.

To do so, it provides the Ory Permission Language that is a very small subset of typescript that provides a way to declare classes that implement the concept of Namespace, relationship between those and predicate permissions on them.

It is meant to be used independently of the other components, like hydra.

https://www.ory.sh/docs/keto/guides/simple-access-check-guide

As we can see in the above sequence diagram, they do not even show a possible use of hydra. That explains why it does not deal with directly integration custom claims in hydra but instead provides a webhooks mechanism.

In the end, we define the models of Namespace -> relations -> OtherNamespace and the predicates Namespace.permission(Namespace) that may go through this graph to answer yes or no.2

The model can also defines relations Namespace -> relations -> SubjectSet<OtherNamespace, "relation"> that means that we can also create relations between instances of Namespace and instances connected by “relation” to some instance of OtherNamespace. This allows defining RBAC, for people are put in groups and groups are linked to roles and then we might want to make relations such as “people that are members of group admin have role admin” that would translate into “role:admin is in relation ‘Role -> SubjectSet(Group, members)’ with the group:admin”. The later is a bit weaker because it does not say that the relation “SubjectSet<Group, members>” is about Users, but this is admittedly easily inferred by the language..

Then, we instantiate subjects, objects and relations and ask keto whether an instance (called an objects) of a OtherNamespace may grant a permission on another instance (called a subject) of a Namespace.3

In fact, the documentation does not say much about how to instantiate users Namespaces. There are examples4, 5 of defined relations. I assume that we only define relations. After all, because it is a simple graph database without data associated with the nodes, you can simple define edges and not the nodes.

Ory Permission Language

Namespace

Relationship

Relationships are facts about entities stored in Ory Permissions. A relationship consists of three elements: an object entity, a relation string, and a subject entity.

https://www.ory.sh/docs/keto/guides/simple-access-check-guide

Permissions

Permissions are essentially TypeScript functions that return a boolean value based on the relationships in Ory Permissions

https://www.ory.sh/docs/keto/guides/simple-access-check-guide


  1. Ory Keto Permission Server, is the first open-source implementation of the design principles and specifications described in Zanzibar: Google’s Consistent, Global Authorization System.

    https://www.ory.sh/docs/keto/

     ↩︎
  2. Example of a model in which instances of User may be permitted to view, edit, delete or share instances of Document. Note how the User and the Document are not ontologicaly different.

      import { Namespace, SubjectSet, Context } from "@ory/keto-namespace-types"
    
      class User implements Namespace {
        related: {
          manager: User[]
        }
      }
    
      class Group implements Namespace {
        related: {
          members: (User | Group)[]
        }
      }
    
      class Folder implements Namespace {
        related: {
          parents: (File | Folder)[]
          viewers: SubjectSet<Group, "members">[]
        }
    
        permits = {
          view: (ctx: Context): boolean =>
            this.related.viewers.includes(ctx.subject) ||
            this.related.parents.traverse((p) => p.permits.view(ctx)),
        }
      }
    
      class File implements Namespace {
        related: {
          parents: (File | Folder)[]
          viewers: (User | SubjectSet<Group, "members">)[]
          owners: (User | SubjectSet<Group, "members">)[]
        }
    
        // Some comment
        permits = {
          view: (ctx: Context): boolean =>
            this.related.parents.traverse((p) => p.permits.view(ctx)) ||
            this.related.viewers.includes(ctx.subject) ||
            this.related.owners.includes(ctx.subject),
    
          edit: (ctx: Context) => this.related.owners.includes(ctx.subject),
        }
    
    --- https://www.ory.sh/docs/guides/permissions/overview
    
     ↩︎
  3. $ ory is allowed User:Patrik view File keto/src/main.go Allowed

    https://www.ory.sh/docs/guides/permissions/overview

     ↩︎
  4. // user1 has access on dir1 dir1#access@user1

    // This is an empty relation. dir1#child@(file1#)

    // Everyone with access to dir1 has access to file1. file1#access@(dir1#access)

    // Direct access on file2 was granted. file2#access@user1

    // user2 is owner of file2 file2#owner@user2

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

    https://www.ory.sh/docs/keto/concepts/graph-of-relations

     ↩︎
  5. chats:memes#member@PM chats:memes#member@Vincent chats:memes#member@Julia

    chats:cars#member@PM chats:cars#member@Julia

    chats:coffee-break#member@PM chats:coffee-break#member@Vincent chats:coffee-break#member@Julia chats:coffee-break#member@Patrik

    https://www.ory.sh/docs/keto/guides/list-api-display-objects

     ↩︎