ABAC in microservices - abac

I am applying the ABAC methodology for access to protected resources.
My question is what is the best way to apply limits to certain fields that returns the api according to the user who is invoking it.
For example:
I want to allow access to /get-data to authenticated users, /get-data returns:
Date
Names
Address
Balance
I want to show the "balance" field only to users who are allowed access to view amounts, such as a counter.
Can I take balance as an attribute of the resource /get-data?

Related

Keycloak Authorization - best practice roles vs groups

I have a web-application secured with Keycloak. To keep the description of the service short, we have Users and Documents as entities in the service. The users may have access to none or more documents and may edit or read the document.
Currently we have roles such as Admin, EndUser, Developer etc. We then keep a database table outside of Keycloak that maps the documents to users and what user has what access level to what document. All our end-users have the EndUser role in Keycloak. Every single time an EndUser tries to read/edit a Document, we have to make a lookup in the database table for authorization.
We would like to migrate that table to Keycloak. As I understand it I basically have two options:
Create a lot of roles, two for each document with names such as doc_read_[DOCUMENT-ID] and doc_edit_[DOCUMENT-ID] and so on. Then assign the correct role to the correct user. The downside here is that the number of roles will grow A LOT. Also, the number of roles attached to a user will be very large.
Create a group for each document, with the name of the document id. Have different sub-groups for read/write and then add the users in the correct groups. The downside is that the number of groups will be very large. Also, I will rely Authorization on group names, so the list of group names has to be mapped to the token.
I do not want to add a user-attribute with the document-ids to each user. With this approach I can not get an overview of a document and see what users have access to a given Document.
What is the best practice here? Are there any other solutions to solve this issue? This must be a very common setup.
This is just my opinion.
From what I understand both solutions are suboptimal, adding a role per document is unnatural and too finer grain. And as you already mention this would lead to too many roles that probably you will have to add them into the token.
I would personally use Keycloak just for the authentication part and do the authorization part in the backend. I would also try to group the documents in a way that reflect which user roles are allowed to manipulate them.
Alternatively you might try to use Keycloak's Authorization features to handle that use-case, however I have never used it, so there is not much that I can say about this option.
In my opinion what you want to achieve is something that is very tied to your business logic, I wouldn't recomend depending on keycloak to do it. Your token would constantly grow and management would be a nightmare really.
I see no problem in having a service with good cache to lookup permissions, the bulk of the data won't change much over time.

How do I manage authorization (not authentication) with node and a postgresql db?

This question is regarding authorization, not authentication which i will be managing with passportjs. How do i restrict access for data that's bound to specific users without spreading user_id's all over every table in the database?
Should i create a new database user for each new user of my app and restrict access that way? Or is the "user id in every table" approach actually a good way to go?
I'm working on a project right now where someone else wrote the authorization logic and it works using a kind of authorization path in the code so it can find which user a resource belongs to using some breadcrumb logic.
But I'm really at a loss here and I'm having a hard time finding any information regarding this since almost all articles that I find are about authentication rather than authorization. And I do not mean access to a resource, but rather the filtration of data returned from a resource that the user has access to.
If you want to restrict access of users to certain objects, you either have to store that information with the user or with the object.
The latter is the preferred way because it makes permissions disappear with the object. That's the way PostgreSQL does it – it stores an access control list (ACL) with every object.
So you can either use PostgreSQL to implement privileges (then every application user or at least every group with equal privileges has to have a database user, and you can use permissions on tables and columns and row level security), or you implement it in your application and have some sort of ACL with every row in the database.

Odoo v8: How to limit user access to contacts

I'm using Odoo v8 and need a means to prevent certain users (either (preferably) in a sales team or in a user group) from accessing certain contacts (assigned to a different sales team) or the contacts at all.
I tried to achieve this via Record rules but don't seem to get this to work.
Users and user roles are critical points concerning internal security in OpenERP. OpenERP provides several security mechanisms concerning user roles, all implemented in the OpenERP Server. They are implemented in the lowest server level, which is the ORM engine. OpenERP distinguishes three different concepts:
user: a person identified by its login and password. Note that all employees of a company are not necessarily OpenERP users; an user is somebody who accesses the application.
group: a group of users that has some access rights. A group gives its access rights to the users that belong to the group. Ex: Sales Manager, Accountant, etc.
security rule: a rule that defines the access rights a given group grants to its users. Security rules are attached to a given resource, for example the Invoice model.
Security rules are attached to groups. Users are assigned to several groups. This gives users the rights that are attached to their groups. Therefore controlling user roles is done by managing user groups and adding or modifying security rules attached to those groups.
Users
Users represent physical persons using OpenERP. They are identified with a login and a password,they use OpenERP, they can edit their own preferences, … By default, a user has no access right. The more we assign groups to the user, the more he or she gets rights to perform some actions. A user may belong to several groups.
User groups
The groups determine the access rights to the different resources. A user may belong to several groups. If he belongs to several groups, we always use the group with the highest rights for a selected resource. A group can inherit all the rights from another group
Rights
Security rules are attached to groups. You can assign several security rules at the group level, each rule being of one of the following types :
- access rights are global rights on an object,
- record rules are records access filters,
- fields access right,
- workflow transition rules are operations rights.
You can also define rules that are global, i.e. they are applied to all users, indiscriminately of the groups they belong to. For example, the multi-company rules are global; a user can only see invoices of the companies he or she belongs to.
Concerning configuration, it is difficult to have default generic configurations that suit all applications. Therefore, like SAP, OpenERP is by default pre-configured with best-practices.
Access rights
Access rights are rules that define the access a user can have on a particular object . Those global rights are defined per document type or model. Rights follow the CRUD model: create, read (search), update (write), delete. For example, you can define rules on invoice creation. By default, adding a right to an object gives the right to all records of that specific object.
Record rules
When accessing an object, records are filtered based on record rules. Record rules or access filters are therefore filters that limits records of an object a group can access. A record rule is a condition that each record must satisfy to be created, read, updated (written) or deleted. Records that do not meet the constraints are filtered.
For example, you can create a rule to limit a group in such a way that users of that group will see business opportunities in which he or she is flagged as the salesman. The rule can be salesman = connected_user. With that rule, only records respecting the rule will be displayed.
Field access rights
New in version 7.0.
OpenERP now supports real access control at the field level, not just on the view side. Previously it was already possible to set a groups attribute on a <field> element (or in fact most view elements), but with cosmetics effects only: the element was made invisible on the client side, while still perfectly available for read/write access at the RPC level.
As of OpenERP 7.0 the existing behavior is preserved on the view level, but a new groups attribute is available on all model fields, introducing a model-level access control on each field. The syntax is the same as for the view-level attribute:
_columns = {
'secret_key': fields.char('Secret Key', groups="base.group_erp_manager,base.group_system")
}
There is a major difference with the view-level groups attribute: restricting the access at the model level really means that the field will be completely unavailable for users who do not belong to the authorized groups:
Restricted fields will be completely removed from all related views, not just hidden. This is important to keep in mind because it means the field value will not be available at all on the client side, and thus unavailable e.g. for on_change calls.
Restricted fields will not be returned as part of a call to fields_get() or fields_view_get() This is in order to avoid them appearing in the list of fields available for advanced search filters, for example. This does not prevent getting the list of a model’s fields by querying ir.model.fields directly, which is fine.
Any attempt to read or write directly the value of the restricted fields will result in an AccessError exception.
As a consequence of the previous item, restricted fields will not be available for use within search filters (domains) or anything that would require read or write access.
It is quite possible to set groups attributes for the same field both at the model and view level, even with different values. Both will carry their effect, with the model-level restriction taking precedence and removing the field completely in case of restriction.
Note
The tests related to this feature are in openerp/tests/test_acl.py.
Warning
At the time of writing the implementation of this feature is partial
and does not yet restrict read/write RPC access to the field. The
corresponding test is written already but currently disabled.
You can add a Rule for a group of users. I just made it and it's work fine.

Can I rate-limit requests to Parse.com on a per-user basis?

I'm developing an app using Parse.com for BaaS. Aside from regular security checks, it's my understanding/philosophy that part of security is to assume someone HAS broken in, and then limit the amount they can access/delete/mess up.
One way I'd like to do this is to have a per-user rate limit on certain API requests. I can imagine a sort of naive method where I keep a list of who has accessed recently and when, and check that list before allowing a request of that type to go through (I'm thinking beforeSave for various custom classes).
Is there a better, ideally built-in way?
Though Parse.com doesn't have options for configuring this, parse claims that they keep track of suspicious activities and attempt for DDoS attacks are monitored. But not sure to what extend this is possible, because this specific problem is scenario wise relevant/irrelevant.
You dont have an option to do user level rate limit, but they will report any suspicious activities found like redundant hits from same device.
As given in the Parse docs here, They support two levels of permissions, Class level (via Data browser) & Object level (using ACLs)
Configuring class-level permissions
Parse lets you specify what operations are allowed per class. This
lets you restrict the ways in which clients can access or modify your
classes. To change these settings, go to the Data Browser, select a
class, open the "More" dropdown, and click the "Set permissions" item.
Class level permissions is a manual way of giving access to specific users or roles on a class.
In your case, you might probably need object level permissions based on Access Control Lists(ACL).
Access Control Lists
The idea behind an ACL is that each object has a list of users and roles along with what permissions that user or
role has. A user needs read permissions (or must belong to a role that
has read permissions) in order to retrieve an object's data, and a
user needs write permissions (or must belong to a role that has write
permissions) in order to update or delete that object
Create a new role and add list of users to that role who can access. Then set an ACL like this on the other objects.
{ "role:YourRoleName":{"read":true, "write" : true}}
You can now dynamically add or remove users in that role without updating individual objects.

Define parameterized policy in OpenAM

We're looking into using OpenAM to handle security for a web app that we've created. I'm wondering about the/a proper way to set up policies that can be parameterized by value. Specifically, we sell items by county. Each user purchases either a few counties or all counties. I know that we could create a role/group/realm for every county in the US, and assign users to the appropriate roles/groups/realms. But that's a lot of things to manage when we'll never have a user buy more than five. Is there a way I can define a rule or policy to say "allow if the resource's county is in the user's list of counties"?
It seems like this should be possible. But I've been looking through OpenAM documentation, and I can't see a place where it says how to do such a thing.
This should be possible by implementing a custom Policy Condition. In your condition you could check the accessed URL (the policy evaluation mode needs to be self though) and you should have also access to the user's session ID, which should allow you to determine if the given user has the necessary privileges to access the given resource.
The documentation is a little bit sparse about this, but should help in general:
http://openam.forgerock.org/openam-documentation/openam-doc-source/doc/dev-guide/index.html#chap-policy-spi

Resources