When implementating role-based access control on the backend with a postgresql, SQLAlchemy, and Flask/FastAPI, can anyone recommend which is the better approach. So far, the roles I have in mind are admin, manager, customer, delivery crew, but I want to build to scale if needed. I plan to run scripts via CLI to seed initial roles and permissions from constants/objects (e.g. enum Roles, enum Permissions and role_permissions = { [role]: [permissions]}). Access to the admin panel requires admin role and there will be 3-5 admins and the concept of organizations is not applicable here. These approaches are what I have come up with so far:
- A user model with an is_superuser/is_rootuser field and a roles many2many field, and a role model with a many2many permissions field. There will be 1 superuser/rootuser for the entire app and superuser/rootuser and admins are created via CLI and script. Using a superuser/rootuser, we can properly manage roles and permissions (e.g. fix issues like accidental deletion of admin role or corruption of roles and permissions), allowing a path for recovery. From the CLI, credentials are entered and then validated for creating a superuser/rootuser. This approach was inspired by Django and the fastapi-users package.
- A user model with a roles many2many field and the role model will have a many2many permissions field; no is_superuser/is_rootuser field. Users with admin role via CLI and script. The role's model will also have a boolean called isSystem, which will also be included during the seeding, and those with isSystem=True cannot be deleted or change their name (e.g. the admin role). Truncate permissions and create and assign permissions when permissions changes.
Feel free to suggest your own approach if you think it is better.