<@U04UQ68083H> how to map subjects to roles/groups...
# ory-copilot
w
@chilly-king-10285 how to map subjects to roles/groups and groups to permissions?
c
A message from kapa.ai
To map subjects to roles/groups and groups to permissions, you can use Ory Keto's relationships. Relationships encode relations between subjects (people or things that want to access resources) and objects (resources you want to manage). 1. First, create relationships between subjects (users) and groups. For example, to add a user to a group, create a relationship from the user (subject) to the group (object) through a
members
relationship:
Copy code
users:user1 is in members of groups:group1
2. Next, define permissions for the groups by creating relationships between the groups and the objects (resources) they can access. For example, to allow members of a group to read a file:
Copy code
members of groups:group1 are readers of files:file1
Remember that Ory Keto supports more advanced permission models like RBAC, ABAC, and beyond. You can use the Ory Permission Language to create permission models that fit your exact use case. For more information on relationships, subjects, and objects, refer to the following documentation: - [Relationships](https://www.ory.sh/docs/keto/concepts/relation-tuples) - [Subjects](https://www.ory.sh/docs/keto/concepts/subjects) - [Objects](https://www.ory.sh/docs/keto/concepts/objects)
w
@chilly-king-10285 How can i convert above message to namespace.ts?
c
A message from kapa.ai
To convert the relationships and permissions mentioned in the previous message to a
namespace.ts
file using the Ory Permission Language (OPL), you can follow these steps: 1. Define the subjects and objects as namespaces:
Copy code
typescript import { Namespace, Context } from "@ory/keto-namespace-types"  class User implements Namespace {} class Group implements Namespace {} class File implements Namespace {}
2. Define the relationships between subjects (users) and groups, and between groups and objects (files):
Copy code
typescript class User implements Namespace {}  class Group implements Namespace {   related: {     members: User[]   } }  class File implements Namespace {   related: {     readers: Group[]   } }
3. Define the permissions for the groups:
Copy code
typescript class User implements Namespace {}  class Group implements Namespace {   related: {     members: User[]   } }  class File implements Namespace {   related: {     readers: Group[]   }   permits = {     read: (ctx: Context): boolean => this.related.readers.traverse((group: Group) => group.related.members.includes(ctx.subject))   } }
The final
namespace.ts
file should look like this:
Copy code
typescript import { Namespace, Context } from "@ory/keto-namespace-types"  class User implements Namespace {}  class Group implements Namespace {   related: {     members: User[]   } }  class File implements Namespace {   related: {     readers: Group[]   }   permits = {     read: (ctx: Context): boolean => this.related.readers.traverse((group: Group) => group.related.members.includes(ctx.subject))   } }
This
namespace.ts
file defines a permission model where users can be members of groups, and groups can have read access to files. The
read
permission checks if the subject (user) is a member of any group that has read access to the file. For more information on Ory Permission Language and creating permission models, refer to the following documentation: - [Ory Permission Language](https://www.ory.sh/docs/keto/reference/ory-permission-language) - [Create a Permission Model](https://www.ory.sh/docs/keto/modeling/create-permission-model)
w
@chilly-king-10285 Describe what this code does:
Copy code
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),
  }
}
c
A message from kapa.ai
This code defines a permission model using the Ory Permission Language (OPL) for managing access to resources (folders and files) based on user roles and group memberships. 1.
User
namespace: Represents users with a
manager
relationship, which is an array of other users who are managers of the current user.
Copy code
typescript class User implements Namespace {   related: {     manager: User[]   } }
2.
Group
namespace: Represents groups with a
members
relationship, which is an array of users or other groups that are members of the current group.
Copy code
typescript class Group implements Namespace {   related: {     members: (User | Group)[]   } }
3.
Folder
namespace: Represents folders with the following relationships: - `parents`: An array of parent folders or files. - `viewers`: An array of groups with access to view the folder. Additionally, it defines a
view
permission that checks if the subject (user) has access to view the folder or if any parent folder permits viewing.
Copy code
typescript 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)),   } }
4.
File
namespace: Represents files with the following relationships: - `parents`: An array of parent files or folders. - `viewers`: An array of users or groups with access to view the file. - `owners`: An array of users or groups who own the file. It defines two permissions: - `view`: Checks if the subject (user) has access to view the file, if any parent folder permits viewing, or if the subject is an owner of the file. - `edit`: Checks if the subject (user) is an owner of the file.
Copy code
typescript class File implements Namespace {   related: {     parents: (File | Folder)[]     viewers: (User | SubjectSet<Group, "members">)[]     owners: (User | SubjectSet<Group, "members">)[]   }    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),   } }
This permission model allows you to manage access to folders and files based on user roles, group memberships, and ownership.
m
@chilly-king-10285 from this, how can i add create a relationship that a user Daniel has permissions to edit a file and view a folder
c
A message from kapa.ai
To create a relationship that a user Daniel has permissions to edit a file and view a folder, you need to add Daniel to the
viewers
relationship of the folder and the
owners
relationship of the file. However, the code provided in the previous response does not include a way to directly add users to these relationships. To achieve this, you would typically use Ory Keto's APIs to create and manage these relationships. You can use the Write API to create the required relation tuples. For example, assuming Daniel has the identifier
users:daniel
, a file has the identifier
files:file1
, and a folder has the identifier
folders:folder1
, you can create the following relation tuples: 1. Add Daniel as a viewer of the folder:
Copy code
{
  "namespace": "Folder",
  "object": "folder1",
  "relation": "viewers",
  "subject": "users:daniel"
}
2. Add Daniel as an owner of the file:
Copy code
{
  "namespace": "File",
  "object": "file1",
  "relation": "owners",
  "subject": "users:daniel"
}
By creating these relation tuples, you establish that Daniel has permissions to edit the file and view the folder according to the permission model defined in the OPL code. For more information on how to use Ory Keto's APIs to create and manage relationships, refer to the following documentation: - [Write API](https://www.ory.sh/docs/keto/reference/rest-api/write) - [Read API](https://www.ory.sh/docs/keto/reference/rest-api/read)
m
@chilly-king-10285 how can i do this using ory-client?
c
A message from kapa.ai
To create relationships using the Ory Keto client, you can follow these steps: 1. Install the Ory Keto client:
Copy code
bash npm install @ory/keto-client
2. Import the client and create an instance:
Copy code
javascript const { OryKetoClient } = require('@ory/keto-client'); const keto = new OryKetoClient('<http://localhost:4466>'); // Replace with your Ory Keto server URL
3. Create the relation tuples for Daniel to have permissions to edit a file and view a folder:
Copy code
javascript async function createRelationships() {   try {     // Add Daniel as a viewer of the folder     await keto.createRelationTuple({       namespace: 'Folder',       object: 'folder1',       relation: 'viewers',       subject: 'users:daniel',     });      // Add Daniel as an owner of the file     await keto.createRelationTuple({       namespace: 'File',       object: 'file1',       relation: 'owners',       subject: 'users:daniel',     });      console.log('Relationships created successfully');   } catch (error) {     console.error('Error creating relationships:', error);   } }  createRelationships();
Replace
<http://localhost:4466>
with your Ory Keto server URL, and update the object identifiers (
folder1
and
file1
) as needed. By running this code, you create the relation tuples that grant Daniel permissions to edit the file and view the folder according to the permission model defined in the OPL code. For more information on the Ory Keto client, refer to the following documentation: - [Ory Keto Client](https://www.npmjs.com/package/@ory/keto-client)
m
@chilly-king-10285 how can i do this using ory-client python sdk only?
c
A message from kapa.ai
@most-dawn-89885 That's a great question, but unfortunately I am only capable of responding to a maximum of five questions per thread. Don't hesitate to create a new thread for any further questions you have though. I'm here to help!