<@U04UQ68083H> In the example for creating a permi...
# ory-copilot
b
@chilly-king-10285 In the example for creating a permission model (https://www.ory.sh/docs/keto/modeling/create-permission-model) there are some permissions declared as functions in the
permits
property. Can you give an example in TypeScript (using the SDK) of defining a relationship between a
User
and a
Document
? Additionally, can you given an example in TypeScript (using the SDK) of performing a permission check for the given models and relationships?
c
A message from kapa.ai
Sure, I can provide examples based on the information given in the knowledge sources. First, let's define a relationship between a
User
and a
Document
in TypeScript using the Ory Permission Language (OPL). This is done by declaring the relationships inside the corresponding class in the OPL. Here's an example:
Copy code
typescript import { Namespace, Context } from "@ory/keto-namespace-types"      class User implements Namespace {}      class Document implements Namespace {     related: {       owners: User[]       editors: User[]       viewers: User[]       parents: Folder[]     }   }
In this example, a
Document
can have
owners
,
editors
,
viewers
, and
parents
(which are
Folders
). Each of these relationships is a many-to-many relationship with
User
or
Folder
objects. Next, let's define permissions in the
permits
property of the
Document
class. These permissions are expressed as TypeScript functions that take a context containing the subject and answer permission checks based on the relationships the object has to the subject. Here's an example:
Copy code
typescript class Document implements Namespace {     related: {       owners: User[]       editors: User[]       viewers: User[]       parents: Folder[]     }        permits = {       view: (ctx: Context): boolean =>         this.related.viewers.includes(ctx.subject) ||         this.related.editors.includes(ctx.subject) ||         this.related.owners.includes(ctx.subject) ||         this.related.parents.traverse((parent) => parent.permits.view(ctx)),     }   }
In this example, a
User
can
view
a
Document
if they are a
viewer
,
editor
, or
owner
of the
Document
, or if they can
view
the parent
Folder
. Please note that these examples are based on the Ory Permission Language (OPL), which is a developer-friendly configuration language defined as a subset of TypeScript. It's designed to be quick to learn and has a familiar source in contrary to other, proprietary languages used to represent permissions[^1^][^2^]. [^1^]: https://www.ory.sh/docs/keto/modeling/create-permission-model#define-relationships-in-the-opl [^2^]: https://www.ory.sh/docs/keto/modeling/create-permission-model#define-permissions-in-the-opl
b
@chilly-king-10285 Thanks but the example you provided is only about defining the permission rules. I would like you to provide examples of how consumers should use and interact with the permissions and relationships using the TypeScript SDK.
c
A message from kapa.ai
Sure, I can provide examples based on the information given in the knowledge sources. To interact with the permissions and relationships using the TypeScript SDK, you can use the
relationship
and
permissions
modules. Here's an example of how to create a relationship and check a permission:
Copy code
typescript // Create a relationship   await ory     .relationship     .createRelationship({createRelationshipBody: {/* ... */}})      // Check a permission   const isAllowed = await ory     .permission     .checkPermission({namespace: "n", /* ... */})     .then(({data}) => data.allowed)
In the
createRelationship
function, you would replace
{/* ... */}
with the details of the relationship you want to create. Similarly, in the
checkPermission
function, you would replace
{namespace: "n", /* ... */}
with the details of the permission you want to check[^1^]. Please note that these examples are based on the Ory SDK V1 upgrade guide[^1^]. [^1^]: https://www.ory.sh/docs/guides/upgrade/sdk-v1#permissions--access-control
b
@chilly-king-10285 Please provide an explicit example of the details of the relationship and permissions that I want to check.
c
A message from kapa.ai
I'm sorry for the confusion, but the knowledge sources provided do not include explicit examples of creating a relationship or checking permissions using the TypeScript SDK. The examples provided in the knowledge sources are for the Golang and JavaScript SDKs, not TypeScript. However, the general structure for creating a relationship and checking permissions would be similar across different languages. Here's a general idea of how you might structure these calls:
Copy code
typescript // Create a relationship   await ory     .relationship     .createRelationship({createRelationshipBody: {namespace: 'users', object: 'user1', relation: 'owns', subject: 'file1'}})      // Check a permission   const isAllowed = await ory     .permission     .checkPermission({namespace: 'users', object: 'user1', relation: 'owns', subject: 'file1'})     .then(({data}) => data.allowed)
In this example, we're creating a relationship where
user1
owns
file1
, and then checking if
user1
has the
owns
permission for
file1
. Please note that this is a hypothetical example and may not work as-is. You should refer to the Ory Keto SDK documentation for the exact syntax and parameters for these functions in TypeScript.
b
@chilly-king-10285 Thanks, that’s better. However, where does the relation value
owns
come from? Based on the initial permission rules that you provided, there is a
view
permission defined in the
permits
property. How is that supposed to be used?
c
A message from kapa.ai
The
owns
relation in the example was just a hypothetical example to illustrate the structure of the function call. In the context of the permission model defined in the knowledge sources, the relations are
view
,
edit
,
delete
, and `share`[^1^][^2^]. The
permits
property in the
Document
class defines these permissions as functions. These functions take a context containing the subject (the user performing the action) and return a boolean value indicating whether the action is permitted based on the relationships the object (the document) has to the subject[^2^]. Here's an example of how the
view
permission is defined:
Copy code
typescript permits = {     view: (ctx: Context): boolean =>       this.related.viewers.includes(ctx.subject) ||       this.related.editors.includes(ctx.subject) ||       this.related.owners.includes(ctx.subject) ||       this.related.parents.traverse((parent) => parent.permits.view(ctx)),   }
In this example, a user can
view
a document if they are a
viewer
,
editor
, or
owner
of the document, or if they can
view
the parent folder[^2^]. When checking permissions using the SDK, you would use the
checkPermission
function with the appropriate namespace, object, relation, and subject. The relation would be one of the permissions defined in the
permits
property, such as
view
,
edit
,
delete
, or
share
. [^1^]: https://www.ory.sh/docs/keto/modeling/create-permission-model#list-permissions-to-check-for-each-object [^2^]: https://www.ory.sh/docs/keto/modeling/create-permission-model#define-permissions-in-the-opl
b
@chilly-king-10285 I’m confused now. According to the quickstart documentation (https://www.ory.sh/docs/guides/permissions/overview) and the examples provided, relationships are created with the
relation
property being one of the
related
properties of the permission rules. However, there is no mention of using the
view
and
edit
permissions (defined as
permits
) when creating the relationships. The documentation also mentions “With the relationships created, try running queries that illustrate use cases”. How does this translate into checking for permissions using the TypeScript SDK?
c
A message from kapa.ai
New message text here
b
@chilly-king-10285 That was helpful thanks
c
A message from kapa.ai
You're welcome! I'm glad I could help. If you have any more questions about Ory or its SDKs, feel free to ask.
b
@chilly-king-10285 Can you suggest how to model permissions using the Ory Permission Language for the following use case: • there is an employee which refers to an identity • employees are part of a company • a company has a SSO configuration • some employees are owners • some employees can manage the SSO configuration of that company • employees that are owners can assign roles to other employees If possible, draw some diagrams to illustrate the relationships between the models.
c
A message from kapa.ai
Sure, I can provide a general idea of how you might model these permissions using the Ory Permission Language (OPL). First, let's define the entities:
Employee
,
Company
, and
SSOConfiguration
.
Copy code
typescript import { Namespace, Context } from "@ory/keto-namespace-types"    class Employee implements Namespace {}    class Company implements Namespace {     related: {       employees: Employee[]       owners: Employee[]       ssoConfigManagers: Employee[]       ssoConfiguration: SSOConfiguration[]     }   }    class SSOConfiguration implements Namespace {   related: {     company: Company[]   } }
In this example, a
Company
can have
employees
,
owners
, and
ssoConfigManagers
(which are all
Employee
objects), and an
ssoConfiguration
(which is an
SSOConfiguration
object). Next, let's define the permissions in the
permits
property of the
Company
class:
Copy code
typescript class Company implements Namespace {     related: {       employees: Employee[]       owners: Employee[]       ssoConfigManagers: Employee[]       ssoConfiguration: SSOConfiguration[]     }      permits = {       manageSSO: (ctx: Context): boolean => this.related.ssoConfigManagers.includes(ctx.subject),       assignRoles: (ctx: Context): boolean => this.related.owners.includes(ctx.subject),     }   }
In this example, an
Employee
can
manageSSO
if they are an
ssoConfigManager
of the
Company
, and can
assignRoles
if they are an
owner
of the
Company
. Please note that this is a hypothetical example and may not work as-is. You should refer to the Ory Keto documentation for the exact syntax and parameters for these functions in TypeScript[^1^][^2^]. As for the diagram, I'm an AI text-based assistant and I'm unable to draw diagrams. However, you can visualize the relationships as follows: -
Company
has relationships to multiple
Employee
entities (as
employees
,
owners
, and
ssoConfigManagers
), and to an
SSOConfiguration
entity. -
Employee
entities are related to a
Company
entity. -
SSOConfiguration
is related to a
Company
entity. [^1^]: https://www.ory.sh/docs/keto/modeling/create-permission-model#define-relationships-in-the-opl [^2^]: https://www.ory.sh/docs/keto/modeling/create-permission-model#define-permissions-in-the-opl
b
@chilly-king-10285 Thanks. Now try to model that using RBAC.
c
A message from kapa.ai
Sure, I can provide a general idea of how you might model these permissions using Role-Based Access Control (RBAC) with Ory. First, let's define the roles:
Employee
,
Owner
, and
SSOConfigManager
.
Copy code
typescript import {{ Namespace, Context }} from "@ory/keto-namespace-types"    class Employee implements Namespace {{}}    class Owner extends Employee {{}}    class SSOConfigManager extends Employee {{}}
In this example,
Owner
and
SSOConfigManager
are roles that inherit from the
Employee
role. Next, let's define the permissions in the
permits
property of the
Company
class:
Copy code
typescript class Company implements Namespace {{     related: {{       employees: Employee[]       owners: Owner[]       ssoConfigManagers: SSOConfigManager[]       ssoConfiguration: SSOConfiguration[]     }}      permits = {{       manageSSO: (ctx: Context): boolean => this.related.ssoConfigManagers.includes(ctx.subject),       assignRoles: (ctx: Context): boolean => this.related.owners.includes(ctx.subject),     }}   }}
In this example, an
Employee
can
manageSSO
if they have the
SSOConfigManager
role in the
Company
, and can
assignRoles
if they have the
Owner
role in the
Company
. Please note that this is a hypothetical example and may not work as-is. You should refer to the Ory Keto documentation for the exact syntax and parameters for these functions in TypeScript[^1^][^2^]. [^1^]: https://www.ory.sh/docs/keto/modeling/create-permission-model#define-relationships-in-the-opl [^2^]: https://www.ory.sh/docs/keto/modeling/create-permission-model#define-permissions-in-the-opl
b
@chilly-king-10285 Provide a usage example with the TypeScript SDK for creating a relationship for different users.
c
A message from kapa.ai
Sure, I can provide a general idea of how you might create a relationship for different users using the TypeScript SDK. Here's a hypothetical example of how you might create a relationship where a user is an
editor
of a document:
Copy code
typescript await ory     .relationship     .createRelationship({createRelationshipBody: {namespace: 'documents', object: 'doc1', relation: 'editors', subject: 'user1'}})
And here's how you might create a relationship where another user is an
owner
of the same document:
Copy code
typescript await ory     .relationship     .createRelationship({createRelationshipBody: {namespace: 'documents', object: 'doc1', relation: 'owners', subject: 'user2'}})
In these examples,
user1
is an
editor
of
doc1
, and
user2
is an
owner
of
doc1
. Please note that these are hypothetical examples and may not work as-is. You should refer to the Ory Keto SDK documentation for the exact syntax and parameters for these functions in TypeScript[^1^]. [^1^]: https://www.ory.sh/docs/guides/upgrade/sdk-v1#permissions--access-control
b
@chilly-king-10285 Sorry I meant the usage example referred to the previous permission rules about Employee, Company, etc.
c
A message from kapa.ai
I see, you want to create relationships for the
Employee
,
Company
, and
SSOConfigManager
roles. Here's a hypothetical example of how you might do that using the TypeScript SDK:
Copy code
typescript // Create an Employee relationship for a Company await ory     .relationship     .createRelationship({createRelationshipBody: {namespace: 'companies', object: 'company1', relation: 'employees', subject: 'employee1'}})  // Create an Owner relationship for a Company await ory     .relationship     .createRelationship({createRelationshipBody: {namespace: 'companies', object: 'company1', relation: 'owners', subject: 'employee2'}})  // Create an SSOConfigManager relationship for a Company await ory     .relationship     .createRelationship({createRelationshipBody: {namespace: 'companies', object: 'company1', relation: 'ssoConfigManagers', subject: 'employee3'}})
In these examples,
employee1
is an
employee
of
company1
,
employee2
is an
owner
of
company1
, and
employee3
is an
ssoConfigManager
of
company1
. Please note that these are hypothetical examples and may not work as-is. You should refer to the Ory Keto SDK documentation for the exact syntax and parameters for these functions in TypeScript[^1^]. [^1^]: https://www.ory.sh/docs/guides/upgrade/sdk-v1#permissions--access-control
b
@chilly-king-10285 Thanks. However, you mentioned that for the RBAC use case you suggest to use dedicated roles (namespaces) such as
Owner
and
SSOConfigManager
. How does this translate when defining relationships for users?
c
A message from kapa.ai
In the context of Role-Based Access Control (RBAC), roles like
Owner
and
SSOConfigManager
are considered as subjects, similar to
Employee
. When defining relationships, you would specify these roles as the subject. Here's a hypothetical example of how you might create a relationship where a user has the
Owner
role for a company:
Copy code
typescript await ory     .relationship     .createRelationship({{createRelationshipBody: {{namespace: 'companies', object: 'company1', relation: 'owners', subject: 'owner1'}})
And here's how you might create a relationship where another user has the
SSOConfigManager
role for the same company:
Copy code
typescript await ory     .relationship     .createRelationship({{createRelationshipBody: {{namespace: 'companies', object: 'company1', relation: 'ssoConfigManagers', subject: 'ssoConfigManager1'}})
In these examples,
owner1
is an
Owner
of
company1
, and
ssoConfigManager1
is an
SSOConfigManager
of
company1
. Please note that these are hypothetical examples and may not work as-is. You should refer to the Ory Keto SDK documentation for the exact syntax and parameters for these functions in TypeScript[^1^]. [^1^]: https://www.ory.sh/docs/guides/upgrade/sdk-v1#permissions--access-control
b
@chilly-king-10285 Can you provide now a suggestion on how to model the permissions for the previously defined use case using ABAC?
c
A message from kapa.ai
Sure, I can provide a general idea of how you might model these permissions using Attribute-Based Access Control (ABAC) with Ory. First, let's define the entities:
Employee
,
Company
, and
SSOConfiguration
.
Copy code
typescript import { Namespace, Context } from "@ory/keto-namespace-types"    class Employee implements Namespace {}    class Company implements Namespace {     related: {       employees: Employee[]       owners: Employee[]       ssoConfigManagers: Employee[]       ssoConfiguration: SSOConfiguration[]     }   }    class SSOConfiguration implements Namespace {   related: {     company: Company[]   } }
In this example, a
Company
can have
employees
,
owners
, and
ssoConfigManagers
(which are all
Employee
objects), and an
ssoConfiguration
(which is an
SSOConfiguration
object). Next, let's define the permissions in the
permits
property of the
Company
class:
Copy code
typescript class Company implements Namespace {     related: {       employees: Employee[]       owners: Employee[]       ssoConfigManagers: Employee[]       ssoConfiguration: SSOConfiguration[]     }      permits = {       manageSSO: (ctx: Context): boolean =>         this.related.ssoConfigManagers.includes(ctx.subject),       assignRoles: (ctx: Context): boolean =>         this.related.owners.includes(ctx.subject),     }   }
In this example, an
Employee
can
manageSSO
if they are an
ssoConfigManager
of the
Company
, and can
assignRoles
if they are an
owner
of the
Company
. Please note that this is a hypothetical example and may not work as-is. You should refer to the Ory Keto documentation for the exact syntax and parameters for these functions in TypeScript[^1^][^2^]. [^1^]: https://www.ory.sh/docs/keto/modeling/create-permission-model#define-relationships-in-the-opl [^2^]: https://www.ory.sh/docs/keto/modeling/create-permission-model#define-permissions-in-the-opl
b
@chilly-king-10285 Explain how and why these models can be used for ABAC.
c
A message from kapa.ai
Attribute-Based Access Control (ABAC) is a flexible and powerful model that can be used to manage permissions in complex scenarios. It allows for fine-grained access control based on the evaluation of attributes associated with the subject (user), object (resource), requested action, and the environment. In the context of the
Employee
,
Company
, and
SSOConfiguration
models, ABAC can be used to control access based on specific attributes of these entities. For example, an
Employee
can be granted the ability to manage the
SSOConfiguration
of a
Company
if they have the
ssoConfigManager
attribute. Similarly, an
Employee
can be granted the ability to assign roles to other employees if they have the
owner
attribute. Here's how the permissions are defined in the
permits
property of the
Company
class:
Copy code
typescript class Company implements Namespace {{     related: {{       employees: Employee[]       owners: Employee[]       ssoConfigManagers: Employee[]       ssoConfiguration: SSOConfiguration[]     }}      permits = {{       manageSSO: (ctx: Context): boolean =>         this.related.ssoConfigManagers.includes(ctx.subject),       assignRoles: (ctx: Context): boolean =>         this.related.owners.includes(ctx.subject),     }}   }}
In this example, the
manageSSO
and
assignRoles
permissions are granted based on the
ssoConfigManager
and
owner
attributes of the
Employee
, respectively[^1^]. The advantage of ABAC is that it allows for a high degree of customization and flexibility. It can handle complex access control scenarios that can't be easily managed with simpler models like Role-Based Access Control (RBAC). However, it can also be more complex to implement and manage due to the need to define and evaluate multiple attributes. [^1^]: https://www.ory.sh/docs/keto/modeling/create-permission-model#define-permissions-in-the-opl
b
@chilly-king-10285 Explain how and why these models can be used for RBAC.
c
A message from kapa.ai
Role-Based Access Control (RBAC) is a model that can be used to manage permissions based on the roles that users have within the system. It simplifies management and understanding of access control by mapping users to roles and roles to permissions. In the context of the
Employee
,
Company
, and
SSOConfiguration
models, RBAC can be used to control access based on the roles that an
Employee
has in a
Company
. For example, an
Employee
can be assigned the
Owner
or
SSOConfigManager
role for a
Company
. Here's how the roles are defined:
Copy code
typescript import {{ Namespace, Context }} from "@ory/keto-namespace-types"    class Employee implements Namespace {{}}    class Owner extends Employee {{}}    class SSOConfigManager extends Employee {{}}
In this example,
Owner
and
SSOConfigManager
are roles that inherit from the
Employee
role. And here's how you might create a relationship where a user has the
Owner
role for a company:
Copy code
typescript await ory     .relationship     .createRelationship({{createRelationshipBody: {{namespace: 'companies', object: 'company1', relation: 'owners', subject: 'owner1'}})
And here's how you might create a relationship where another user has the
SSOConfigManager
role for the same company:
Copy code
typescript await ory     .relationship     .createRelationship({{createRelationshipBody: {{namespace: 'companies', object: 'company1', relation: 'ssoConfigManagers', subject: 'ssoConfigManager1'}})
In these examples,
owner1
is an
Owner
of
company1
, and
ssoConfigManager1
is an
SSOConfigManager
of `company1`[^1^]. The advantage of RBAC is that it's simple and intuitive to understand. It's easy to manage access control by assigning users to roles and defining what each role can do. However, it may not be flexible enough to handle complex access control scenarios that require more granular permissions based on specific attributes of the user or resource, which is where Attribute-Based Access Control (ABAC) can be more suitable. [^1^]: https://www.ory.sh/docs/guides/upgrade/sdk-v1#permissions--access-control