careful-honey-27437
05/05/2025, 4:51 AMbrief-egg-61061
05/05/2025, 4:51 AMbrief-egg-61061
05/05/2025, 4:52 AMSubjectSet
as a type when you need to define relationships that involve indirect subjects or implement hierarchical access patterns. A SubjectSet
refers to all subjects who have the same relation on an object. This is particularly useful in the following scenarios: 1. Implementing role-based access control (RBAC): When you want to grant permissions to users based on their roles or group memberships. 2. Creating hierarchical permissions: When you need to implement inheritance of permissions through a hierarchy. 3. Defining indirect relationships: When subjects are related to objects through other subjects. Here's an example from the Ory Permission Language documentation: typescript class User implements Namespace { related: { manager: User[] } } class Group implements Namespace { related: { // Members can be Users or other Groups members: (User | Group)[] } } class Folder implements Namespace { related: { parents: Folder[] // SubjectSet<Group, "members"> refers to all subjects that are members of a Group viewers: SubjectSet<Group, "members">[] } permits = { view: (ctx: Context): boolean => this.related.viewers.includes(ctx.subject) || this.related.parents.traverse((p) => p.permits.view(ctx)), } }
In this example, SubjectSet<Group, "members">
is used to indicate that all members of a Group should have the "viewers" relation to a Folder. This means that if a Group has the "viewers" relation to a Folder, all members of that Group will inherit that relation. The syntax for SubjectSet
is SubjectSet<T, "r">
where: - T
is the namespace (class) that contains the relation - "r"
is the name of the relation in that namespace This powerful feature allows you to create complex permission models with minimal explicit relationship definitions, as it leverages the graph of relations to determine permissions [Graph of relations](https://www.ory.sh/docs/keto/concepts/graph-of-relations).careful-honey-27437
05/05/2025, 4:53 AMbrief-egg-61061
05/05/2025, 4:53 AMbrief-egg-61061
05/05/2025, 4:54 AMSubjectSet
in certain places to create more efficient indirect relationships. Let me explain where and why: ## Where to Use SubjectSet In your current configuration, you're using the traverse
method to check permissions across hierarchical relationships (from Article to Publication to Organization). While this works, using SubjectSet
could simplify some relationships and make your permission model more efficient in specific scenarios. For example, in the Publication
namespace, you could use SubjectSet
to directly reference Organization admins and owners: typescript class Publication implements Namespace { related: { organizations: Organization[] admins: User[] editors: User[] // Add these SubjectSets to directly reference organization roles organizationAdmins: SubjectSet<Organization, "admins">[] organizationOwners: SubjectSet<Organization, "owners">[] } permits = { // Then you could simplify some permission checks create: (ctx: Context): boolean => this.related.admins.includes(ctx.subject) || this.related.editors.includes(ctx.subject) || this.related.organizationAdmins.includes(ctx.subject) || this.related.organizationOwners.includes(ctx.subject), // Other permissions similarly simplified } }
## Benefits of Using SubjectSet Using SubjectSet
in this way would provide several advantages: 1. Performance: Direct includes
checks are generally more efficient than traversing relationships and checking permissions recursively [Graph of relations](https://www.ory.sh/docs/keto/concepts/graph-of-relations). 2. Clarity: The permission model becomes more explicit about which roles from parent objects have which permissions. 3. Flexibility: It allows you to selectively grant permissions to specific roles from parent objects rather than inheriting all permissions. ## When to Keep Your Current Approach Your current approach using traverse
is appropriate when: 1. You want to maintain a strict hierarchical permission model where changes to parent permissions automatically propagate. 2. The permission logic at each level is complex and can't be easily represented by simple role membership. 3. You need to check different permissions at different levels of the hierarchy. The current model is valid and follows good practices for hierarchical permissions in Ory Permission Language. Whether to introduce SubjectSet
depends on your specific requirements for performance, maintainability, and the exact semantics of your permission model. If you decide to keep your current approach, it's still well-structured and follows the principles of the Ory Permission Language [What is the Ory Permission Language](https://www.ory.sh/blog/what-is-the-ory-permission-language).