I'm trying to determine the best approach for a RBAC and ACL system. I want to store the roles and ACLs in the DB for easy updating in the future, so I don't think I can use the Roles and Permissions feature in the Security Provider. The Security Provider will stay a simple "is the user logged in" enforcer.
At the moment I'm thinking I'll need to add DB queries at the beginning of my API's Request Methods to check if the user has the appropriate rights before running any of the steps.
In addition to the tables that will store the data (tasks, contacts, etc.), I have created the following tables for the RBAC/ACL system.
- Account Table : Represents different accounts or organizations within the system.
- Contains: Account IDs, account names, and other relevant details.
- User Table : Stores information about users.
- Contains: User IDs, names, account IDs they belong to, and a reference to roles.
- Relationship: Each user is associated with one account (foreign key to the Account table).
- Relationship: Each user is associated with one to many roles.
- Role Table : Contains different roles that can be assigned to users.
- Contains: Role IDs, role names (like Admin, Editor, User), and descriptions.
- Relationship: Each role is associated with one to many permissions.
- Permission Table : Defines various permissions or actions that can be performed.
- Contains: Permission IDs, names (like 'read', 'write'), and descriptions.
- ACL Table : Defines specific access control rules.
- Contains: ACL entries that link users or roles to specific resources, specifying what access (defined in Permission Table) they have to those resources.
In this structure, users are linked to accounts and roles, roles are linked to permissions, and the ACL table provides specific access rules, tying users (or their roles) to particular resources (i.e. tasks, contacts, etc.) with defined permissions. This setup should allow for both broad, role-based permission assignment and more specific, user-resource-level permissions via the ACL.
For example, I have a task table. All tasks are related to an account. Each user is also related to an account, so they should only interact with tasks related to their account. Each user would also have a role(s) that give(s) them permissions (e.g. can delete, can edit) related to the task module.
The permissions would be tied to the Request Methods in my API. So within the request method to delete condition, I would have a database query that checks if the user is the creator of the record, if they are not, then the next check would be to see if they had a role/permission that allows them to delete.
Further, let's say I wanted to share this task with someone that is not a part of the account, this is where I would create a record in the ACL table specifying the user_id, the task_id, and read access through a "Share" action and I would also build the checks into the GET method that would happen after the check for creator and user role/permission.
Any thoughts on anything I may be missing or a better design?