Michał Wójcik
10/07/2025, 9:50 AMresource_type for each level (e.g., car, engine, engine_part),
2. Or using some other pattern (like nested attributes, resource instances, or metadata-based policies)?
My main concern is scalability — if each car has many parts, then modeling each part as a separate resource type could lead to a very large and complex model.
How would you recommend approaching this problem in Permit.io?Ask Inkeep
10/07/2025, 9:50 AMAsk Inkeep
10/07/2025, 9:50 AMcar, engine, engine_part) and connect them using *relations* . This is similar to how Google Drive models folders containing files .
Here's how to model your Car → Engine → Parts hierarchy:
1. Define Resources with Relations
await permit.api.create_resource(
{
"key": "engine_part",
"name": "Engine Part",
"actions": {
"read": {},
"update": {},
"replace": {}
},
"roles": {
"maintainer": {
"name": "Maintainer",
"permissions": ["read", "update", "replace"]
},
"viewer": {
"name": "Viewer",
"permissions": ["read"]
}
}
}
)
await permit.api.create_resource(
{
"key": "engine",
"name": "Engine",
"actions": {
"read": {},
"service": {},
"modify": {}
},
"roles": {
"engineer": {
"name": "Engineer",
"permissions": ["read", "service", "modify"]
},
"inspector": {
"name": "Inspector",
"permissions": ["read"]
}
}
}
)
2. Create Relations Between Resources
await permit.api.resource_relations.create(
"engine_part",
{
"key": "parent",
"name": "Parent",
"subject_resource": "engine",
}
)
await permit.api.resource_relations.create(
"engine",
{
"key": "parent",
"name": "Parent",
"subject_resource": "car",
}
)
3. Enable Permission Inheritance
Configure roles to inherit permissions through the parent relationship :
await permit.api.resource_roles.update(
"engine_part",
"maintainer",
{
"granted_to": {
"users_with_role": [
{
"linked_by_relation": "parent",
"on_resource": "engine",
"role": "engineer",
}
]
}
}
)
Why This Approach Works
1. *Scalability*: Relations define the structure once; you then create relationship tuples between instances . This scales better than creating unique resource types for each part.
2. *Hierarchical Permissions*: Users with engineer role on an engine automatically get appropriate permissions on all its parts .
3. *Fine-Grained Control*: You can still assign direct permissions to specific parts when needed .
4. *Resource Instances*: Each car, engine, and part becomes a resource instance :
await permit.api.resource_instances.create(
{
"resource": "engine_part",
"key": "spark_plug_123",
"tenant": "default",
}
)
This ReBAC approach mirrors how Google Drive handles folder-level access granting permissions to contained files , making it ideal for your hierarchical authorization needs.Ask Inkeep
10/07/2025, 9:50 AMOr Weis
10/07/2025, 10:04 AMThomas
10/07/2025, 1:39 PM