Role based access control pattern design - database

I'm currently working on a project where a user can have many roles, and each role has assigned one or many permissions. Permissions describe the actions that a user can apply to ressources. For example let's consider that I have three ressources that I can interact with using my API : users, books, payments.
I'd like to have all users able to update their personal informations like phone number... etc. This led me to give update permission on user's ressource for all users. But the problem is that I want them to be able to updates their own profiles only. Furthermore, some users have admin permissions and can change other users permissions, therefor they have another kind of update permission on user's resource.
So my question is : what's the best way to design the permission table. Below you can find my schema design. Thank you for your answers in advance.
User(firstName string, lastName string, roles Role[])
Role(name string, description string, permissions Permission[])
Permission(name string, effect 'Allow' | 'Deny', resource string, action string)

Well I am not entirely sure what you meant by resource and action. If you meant URI template and HTTP method, then ok. Otherwise you might need a different solution or somehow add parameters to your design if you want to allow or deny individual resources per id.
If we are talking about a REST API, which I assume, then you can do something like PATCH /api/v1/current-user/profile {...} for updating your profile and PATCH /api/v1/users/{user-id}/profile {...} to update somebody else's profile. If you meant controller classes and their methods, then you can do the same with two different controllers, something like CurrentUser.partialUpdate(params) and User.partialUpdate(params).
As of updating user permissions, I wonder how to do it, because you can update only role permissions and give or take away roles for the users in your model.
Another thing I don't understand that why do you need the allow|deny flags. If roles collide because users can have multiple roles or permissions collide, because you can both allow and deny the same thing, then how do you resolve it without a hierarchy? And if you don't have a hierarchy, then this flag is completely useless and just deny all and allow what is added to the role.
As of the one user multiple roles approach it is not a great idea, at least in places where people take security seriously a single account or at least a single session can have only a single role. Since this would make a lot of repetition I would solve this on a role level and make composite roles or support role inheritance. So for example the Administrator role would be the composite of the OwnProfileEditor and ProfileEditor sub-roles, which I would rather call Features or Capabilities or PermissionGroups rather than Roles.
Usually RBAC is not that flexible, so people tend to add per User Permissions to override Role Permissions. I would not do it, because you will end up with a mess if you follow that approach.

Related

What is the best approach to design database with external users, groups and permissions?

We are removing User, User Group and Permission models from our backend in favor of Auth0.
Our first idea was to just delete User, Group and Permission tables from DB and replace related foreign keys with varchar field. In this field we would then enter IDs that we get from Auth0 in JWT (pointing to something not present in our DB).
Is this good approach? I somehow feel that there must be more "relational" way of doing this.
Generally OAuth will not do all of the permission checks for you. Instead it gives you general mechanisms to sign the user in and issue + validate tokens.
In most real world architectures you also need to manage a second level of authorization in your back end - using domain specific user data for roles, permissions etc.
A couple of write ups of mine may help:
User Data Management
API Authorization
Auth0 Community Manager Dan here,
In this scenario you may be able to leverage the RBAC to replace your existing users/groups/permissions setup.
You would register a user's roles and the associated permissions of each role in the Auth0 dashboard or programmatically via the management API. Then you can setup a rule to add user roles to the token.
To connect this user to your existing user data store you can store the Auth0 id, similarly to how you have described.
This allows you to lookup the user when the token is received, and to associate any permissions or roles the user has. You can make roles API-specific by adding a prefix to the role, or have roles be general depending on your needs.

Salesforce Roles

I have roles hierarchy in place.
the new requirement is to set up permission to specific external users so they will not be able to see other users records.
the sharing setting for the object is set to Private. I cannot create a user without a role. Other users should be able to see other users (in their role) records. but only this few users should be able to see only records they own.
any idea how to solve it?
thanks,
Chen

How to restrict a user to access for specific object records without role in Salesforce

I have created an integration profile CORE_AKTANA_DI through which data for objects will be loaded into my Salesforce instance through a third-party user. I have provided "View All" permission for all objects to that profile. However, since this is a global Salesforce org, hence, there is data for other countries as well in this instance.
I want the user with the profile to see only data of France i.e with country "FR". In this case, my only choice is to:
Remove the "View All" permission of the profile from all objects.
Give the user a role such as "FR-Corp".
Create sharing rules for all objects with "Private" OWD and share with this role.
The problem is that since this is an integration profile, I cannot assign a role to the user with this profile. Also, it is not plausible to create sharing rules since there are a lot of objects with private OWD.
Same problem occurs by assigning the user to a public group, i.e a lot of sharing rules need to be created.
In this case, please suggest me the easiest possible options.
Actually, how to solve your issue is dependent on business process you are trying to implement. There are few ways:
sharing by hierarchy: setting proper roles and checking 'grant access using hierarchy'
sharing rules: setting proper sharing rules, owner/criteria based
manual sharing: using button
sharing using apex: using share object of any corresponding object
I think, this document will be useful for you.
I don't think what you say is correct:
"The problem is that since this is an integration profile, I cannot assign
a role to the user with this profile."
In my org we have a few integration connections. Each connection is anchored by a SF user license which has both Role and Profile. You should likely give the integration it's own user license and name the user something like "Integration (Fr)" Set the Roll up with appropriate hierarchy position, permissions and sharing rules and once you've done all the token resets needed set as API login only & password never expires. That should do it unless I'm missing something.

Configure CouchDB as read-only for non-admins

I recently set up CouchDB on my server, but I'm running into a lack of information regarding changing permissions. I have an admin account, so it's not an admin party, but the restrictions are still looser than I'd like.
I'd like the Futon interface (which I've exposed) to be read-only for unauthenticated users. If I understand correctly, as it is, any visitor to the exposed Futon interface can become a member, who is
allowed to read all documents and create and modify any document except for design documents.
I'd like to take these abilities away, and configure CouchDB so that unauthenticated users can neither create documents nor become users. Basically, I want CouchDB to be read-only for everyone besides me.
Looking at the docs about security, there are ways to restrict access to the database of any kind to registered members, but I'd like to keep letting unauthenticated users have read-only access. According to this page,
If there are any member names or roles defined for a database, then only authenticated users having a matching name or role are allowed to read documents from the database (or do a GET /{db} call).
so that would restrict read access as well.
Are there any ways to fine-tune the permissions settings on CouchDB?
To simply solve your problems, assign your admin a role (eg: "ADMIN").
Then, foreach databases, restrict the "Admin" permissions to the role "ADMIN".
By default, a newly registered user won't have any role so he won't be able to access a database as an admin.
I ended up using nginx configuration to block all non-GET requests. This allows anyone to read the database, but prevents writing to the database.
However:
I can't safely expose futon now
As an admin, I can't edit the database
but to solve these
I could potentially write a new interface for CouchDB that only exposed read functionality
I can do my administration through SSH port forwarding.
If nginx blocking isn't secure, I'd love it if someone could let me know 😄

Securing Web api Role Based

I hope you're fine, this is my first question and I really don't know where to start from, so here it is,
I've been trying to build a sample with Microsoft Web api Template where I have to authorize users based on roles for example "Admin, Moderators, etc..." so, the thing is the I don't want to put all those roles on the top of the controller like
[Authorize ( Roles ="Admin, Moderators, etc...")]
I see this as not a good practice because What happens if I create another role in my db? I will have to modify the controller to add the new Role xD, really bad, isn't it? so the question is. How to extend some class like AuthorizeFilter to get the roles from database and validate with the controller? I mean if there is a user who is in the role admin authorize it and viceversa?
the other question is How to build a great authorzationfilter which can manage something like if a user if in Moderator Role but the only right he has is to user the Create action in the controller?
I hope you can help me with an example...
Thanks in advance
Ps. Sorry for my english
I agree role based authorization is somehow limited and authorize attribute is a bit rigid.
In some scenarios role based authorization is not enough, you need to extend it. You can introduce the permission concept. Instead of be a requirement that you have to be a member of a specific role to execute an action, you could state that to be authorized to execute an action you need a specific permission. So instead of authorize attribute you use RequiredPermisionAttribute. Of course you need to write RequiredPermissionAttribute as an authorization filter.
In the database you have the Permissions Table, the RolesTable, the RolePermissions table and UsersInRole table.
So a user can be a member of one or more roles. A role can have one or more permissions. A user has a specific permission if he/she is a memeber of a role that has that permission.
The required permission filter checks if the logged in user is a member of a role that has the permission, if not, then returns 401 not authorized.
This is a more flexible approach, actions are not tied to roles and roles don't have a fixed number of permissions.

Resources