Hi, Quick context: We’re building a multi-module ...
# permit-saas
u
Hi, Quick context: We’re building a multi-module admin panel where each feature (Leaves, Projects, Attendance, WRM, etc.) has a few high-level permissions like
view
,
create
,
edit
, and
audit
. We don’t want to map all 300+ API endpoints individually inside Permit. Instead, we want Permit to manage only feature-level permissions, and then our Django backend will map API routes to those permissions internally. We also want to dynamically generate the sidebar based on the permissions Permit returns, so that each user only sees the modules they are allowed to access. One thing we need guidance on: How do we best structure resources and resource sets in Permit so that we can group permissions cleanly (ex: Leaves-related permissions → Leaves sidebar items, Projects → Project sidebar items) and also keep a clean mapping between features and the many API endpoints behind them? Basically, Permit will be the single source of truth for “feature permissions,” and Django will handle API-level mapping internally — but we want to know the neatest way to aggregate and organize these resources inside Permit so that the structure scales well.
a
Hi @Utham Prabhu, I'm an AI assistant for Permit.io. I'll analyze available sources and get back to you shortly.
For your multi-module admin panel, you should structure Permit.io resources at the feature level, with each module (Leaves, Projects, Attendance, WRM) as a separate resource. (1) This approach aligns perfectly with your goal of managing feature-level permissions while letting Django handle the API endpoint mapping internally. Recommended Structure Resources Define each module as a resource with its high-level actions. Based on the documentation, resources are defined with their actions like this:
Copy code
# Example from Django integration
action = 'create'
resource = 'Post'
permitted = await permit.check(check.user, action, resource)
(2) For your case, you'd have resources like: •
Leaves
with actions:
view
,
create
,
edit
,
audit
•
Projects
with actions:
view
,
create
,
edit
,
audit
•
Attendance
with actions:
view
,
create
,
edit
,
audit
•
WRM
with actions:
view
,
create
,
edit
,
audit
Dynamic Sidebar Generation You can use bulk permission checks to efficiently determine which modules a user can access. (3) The documentation shows this pattern:
Copy code
await permit.loadLocalStateBulk([
    { action: "view", resource: "Topics_for_you", {
        country: user.publicMetadata.country,
        channel: user.publicMetadata.channel,
    }},
    // ... more checks
]) ;
For your sidebar, adapt this to check view permissions across all modules:
Copy code
// Conceptual example based on the pattern
await permit.loadLocalStateBulk([
    { action: "view", resource: "Leaves" },
    { action: "view", resource: "Projects" },
    { action: "view", resource: "Attendance" },
    { action: "view", resource: "WRM" }
]) ;
Then conditionally render sidebar items based on these permissions. Resource Sets for Grouping If you need more granular control within modules, Resource Sets can help segment resources based on attributes. (4) For example:
Copy code
{
  "allOf": [
    {
      "resource.module": {
        "equals": "Leaves"
      }
    }
  ]
}
(5) This allows you to create condition-based policies while maintaining your clean feature-level structure. Django Integration Pattern In your Django backend, implement a middleware or decorator that maps API endpoints to Permit permissions: (2)
Copy code
# Based on Django integration example
async def your_api_endpoint(request) :
    action = 'create'  # Map from your internal logic
    resource = 'Leaves'  # Map from your module
    
    permitted = await permit.check(user_id, action, resource)
    
    if permitted:
        # Process the request
        return JsonResponse({"message": "User is permitted"})
    else:
        return JsonResponse({"message": "User is not permitted"}, status=403)
This keeps Permit as your single source of truth for feature permissions while Django handles the endpoint-to-permission mapping internally. Scaling Considerations • Keep resources at the feature/module level (not individual endpoints) (1) • Use roles to group common permission sets • Consider using tenants if you have multi-organization requirements • Leverage Resource Sets only when you need attribute-based segmentation within modules (4) This structure scales well because you're managing permissions at the logical feature level rather than the implementation level (300+ endpoints) , while still maintaining fine-grained control through your Django backend.
To learn more, see the sources I considered: [[1] Policy Basics](https://docs.permit.io/how-to/build-policies/policy-basics) [[2] Implementing Fine-grained Authorization in Django Application](https://docs.permit.io/quick-start/django) [[3] Custom UX with Feature Toggling](https://docs.permit.io/modeling/feature-flagging) [[4] Fintech / Banking Demo Application](https://docs.permit.io/modeling/mesa-verde) [[5] Condition Set Rules](https://docs.permit.io/api/working-with-abac/condition-set-rules)
o
Your question specifying resource-sets specifically guided the AI to focus on that, but I think a ReBAC hierarchy based solution would be more natural. both due to the nesting of objects (e.g. Leaves > Leaves sidebar, Projects > Projects) and for using get-user-permissions to easily map out what the current user has access to. @Ask Inkeep give it another go
👀 1
a
Thanks for tagging me @Or Weis. I'll look through relevant sources and get back to you shortly.
You're absolutely right - a ReBAC hierarchy is a more natural fit for your multi-module admin panel structure. ReBAC allows you to model hierarchical structures and inherit permissions through relationships, which maps perfectly to your module → sidebar items structure (1) . ReBAC Structure for Your Admin Panel Parent-Child Hierarchy Design ReBAC visualizes authorization as a graph where each node represents a resource and edges represent relationships . For your case, you'd create a parent-child hierarchy where modules (Leaves, Projects, etc.) are parents of their respective sidebar items and features. The ReBAC model supports role derivation, which means:
A user assigned the role of an Owner on a folder will also get the Owner role on every file within that folder
Applied to your use case: A user with
viewer
role on the
Leaves
module automatically inherits
viewer
permissions on all Leaves-related sidebar items and sub-features. Resource Roles Configuration Instead of flat permissions, you'd define resource-specific roles : •
Leaves#viewer
- can view all Leaves features •
Leaves#editor
- can create/edit in Leaves module •
Leaves#auditor
- can audit Leaves operations •
Projects#viewer
,
Projects#editor
, etc. Resource roles are formatted as
Resource#Role
, making them contextual to specific modules rather than global. Implementation Structure Based on the Mesa Verde banking example (2) , you'd configure:
Copy code
resource "permitio_role" "Leaves_Viewer" {
  key = "viewer"
  name = "Viewer"
  resource = permitio_resource.Leaves.key
  permissions = ["view"]
  depends_on = [permitio_resource.Leaves]
}
Dynamic Sidebar with getUserPermissions The
getUserPermissions
function retrieves all user permissions across resources (3) :
Copy code
await permit.getUserPermissions(user) ;
This returns all permissions for the user, which you can parse to dynamically build the sidebar showing only accessible modules. Role Derivation for Feature Inheritance Configure role derivations so module-level permissions cascade to features (4) : • If a user has
Leaves#editor
role, they automatically get editor permissions on all Leaves sub-resources • This eliminates managing individual feature permissions while maintaining granular control The derivation creates implicit permission grants without explicit role assignments to each instance (1) . Groups for Team Management Use Groups to manage team-based access (5) : 1. Create groups like
HR_Team
or
Finance_Team
2. Assign groups to modules with specific roles 3. Users in groups automatically inherit the module permissions When you add users to a group, they automatically receive permissions assigned to that group . Benefits of ReBAC Approach 1. ​*Hierarchical permission inheritance*​ - Module permissions flow to features automatically (1) 2. ​*Reverse queries*​ - Easily determine who has access to what using
authorized_users
(3) 3. ​*Clean getUserPermissions*​ - Single call retrieves all module access for sidebar generation 4. ​*Scalability*​ - Add new modules/features without permission explosion (4) This ReBAC structure maintains Permit as your single source of truth for feature-level permissions while Django handles the API endpoint mapping, with the added benefit of natural hierarchical permission flow.
To learn more, see the sources I considered: [[1] What is ReBAC?](https://docs.permit.io/how-to/build-policies/rebac/overview) [[2] Fintech / Banking Demo Application](https://docs.permit.io/modeling/mesa-verde) [[3] Advanced Authorization Queries](https://docs.permit.io/overview/advanced-authorization-queries) [[4] What is Relationship-Based Access Control (ReBAC)?](https://www.permit.io/blog/what-is-rebac) [[5] Managing Groups via UI](https://docs.permit.io/api/rebac/groups-ui)
u
@Or Weis (Permit.io) Here’s the flow we’re building: Our application is designed to be multi-tenant. Each tenant will have its own Admin Panel where the admin can assign roles and control access for users within that organization. For example, in Organization A, the admin might assign Bob the HR role. To create this role, the admin selects the resources (screens/features) that an HR user should have access to, and saves this configuration under the “HR” module. Once Bob is assigned this HR role, those permissions immediately apply across the application. When I say “resources,” I’m referring to the same resource model that Permit.io uses — The Policy editor page clone in our admin panel. Our senior developer mentioned that we’ll use the Permit.io SDK to sync these resource selections from our Admin Panel directly into Permit’s system. The challenge we’re facing now is how to group resources efficiently, especially when a single resource might correspond to multiple pages or UI areas. We need a clean way to structure resources so that our sidebar/navigation can be dynamically built based on permissions. And the second one is about our Admin panel for each tenant we show and the policy editor like changes in our panel and also the permit.io (how can we group the resources etc) My question is: Am I mixing methodologies or misunderstanding what Permit.io is meant to solve? And based on this approach, what is the best way to proceed with integrating Permit.io for multi-tenant role and resource management? Would appreciate your insights and recommended next steps.
o
I recommend the ReBAC approach mentioned above to create a hierarchy (a graph) of objects (resource instances) allowing one role assignment on one resource instance to derive multiple roles on other resource instances based on their relationships. @Ask Inkeep please provide an example of role derivations matching the usecase described here, and links for further reading about ReBAC
🙌 1
a
Thanks for tagging me @Or Weis. I'll look through relevant sources and get back to you shortly.
For your multi-tenant admin panel with HR roles and dynamic resource grouping, here's how ReBAC role derivations would work: ReBAC Role Derivation Example for Your Use Case When an admin assigns Bob the "HR" role at the module level, ReBAC automatically derives permissions for all HR-related resources through relationships (1) . Setting Up the Hierarchy Create a parent-child relationship where HR module is the parent of HR-related resources (screens/features) (2) :
Copy code
await permit.api.resource_relations.create(
    "hr_screen",
    {
        "key": "parent",
        "name": "Parent",
        "subject_resource": "hr_module"
    }
)
Configuring Role Derivations Set up role derivation so that module-level roles cascade to all child resources (3) :
Copy code
await permit.api.resource_roles.update(
    "hr_screen",
    "editor",
    {
        "granted_to": {
            "users_with_role": [
                {
                    "linked_by_relation": "parent",
                    "on_resource": "hr_module",
                    "role": "editor"
                }
            ]
        }
    }
)
This means when Bob gets
hr_module#editor
, he automatically receives
hr_screen#editor
on all HR screens where the module is the parent (1) . Multi-Tenant Implementation For each tenant (Organization A, B, etc.) , create relationship tuples linking resources (3) :
Copy code
await permit.api.relationship_tuples.create(
    {
        "subject": "hr_module:org_a",
        "relation": "parent",
        "object": "leave_management:org_a"
    }
)
Practical Example Flow 1. Admin creates "HR" role in Organization A 2. Admin selects resources: Leave Management, Employee Records, Payroll 3. System creates relationships:
hr_module:org_a
→ parent →
leave_management:org_a
(1) 4. Bob is assigned
hr_module:org_a#editor
5. Bob automatically gets editor permissions on all child resources through role derivation The ReBAC policy for this would be: "A user assigned the role
HR_Module#Editor
will also be assigned the
Screen#Editor
when the
HR_Module
instance is the
Parent
of a
Screen
instance" (4) . Dynamic Sidebar Generation Use the derived permissions to build navigation - users only see modules/screens they have access to through the relationship graph (2) . Further Reading on ReBAC • *What is ReBAC? * (1) - Core concepts of relationship-based access control • *Building ReBAC Policies * (2) - Step-by-step guide for implementing ReBAC • *Google Drive Example * (3) - Complete ReBAC implementation showing folder-file hierarchies • *What is Relationship-Based Access Control (ReBAC) ? * (4) - Detailed blog explaining ReBAC benefits and use cases ReBAC's graph-based approach perfectly fits your need to group resources and manage multi-tenant permissions where one role assignment cascades through related resources (1) .
To learn more, see the sources I considered: [[1] What is ReBAC?](https://docs.permit.io/how-to/build-policies/rebac/overview) [[2] Building ReBAC Policies](https://docs.permit.io/how-to/build-policies/rebac/building-rebac-policies) [[3] Modeling Google Drive Permissions with ReBAC](https://docs.permit.io/modeling/google-drive) [[4] What is Relationship-Based Access Control (ReBAC)?](https://www.permit.io/blog/what-is-rebac)