How to deal with deep level granularization with XACML in enterprise application - wso2

I am using IS WSO2 for authorization with XACML. I am am able to achieve authorization for static resource. But I am not sure with the design when it comes to granularization.
Example : if I have method like getCarDetails(Object User) where I should get only those cars which are assigned to this particular user, then how to deal this with XACMl?
Wso2 provides support for PIP where we can use custom classes which can fetch data from database. But I am not sure if we should either make copy of original database at PDP side or give the original database to PIP to get updated with live data.
Because Cars would be dynamic for the application eg. currently 10 cars assigned to user Alice. suddenly supervisor add 20 more car in his list which will be in application level database. Then how these other 20 cars will be automatically assigned in policy at PDP level until it also have this latest information.
I may making some mistake in understanding. But I am not sure how to deal with this as in whole application we can have lots of this kind of complex scenario where some times we will get data for one user from more than 4 or 5 tables then how to handle that scenario?

Your question is a great and the answer will highlight the key benefits of XACML and externalized authorization as a whole.
In XACML, you define generic, global rules, about what is allowed and what isn't using what I would call high-level attributes e.g. attributes of the vehicle (in your case) or the user (role, department, ...)
For instance a simple rule could be (using the ALFA syntax):
policy viewCars{
target clause actionId=="view" and resourceType=="car"
apply firstApplicable
rule allowSameRegion{
permit
condition user.region==car.region
}
}
Both the user's region and the car's region are maintained inside the application's database. The values are read using a PIP or Policy Information Point (details here).
In your example, you talk about direct assignment, i.e. a user has been directly assigned to a vehicle. In that case, the rule would become:
policy viewCars{
target clause actionId=="view" and resourceType=="car"
apply firstApplicable
rule allowAssignedVehicle{
permit
condition user.employeeId==car.assignedUser
}
}
This means that the assigned user information must be kept somewhere, in the application database, a CSV file, a web service, or another source of information. It means that from a management perspective, an administrator would add / remove vehicles from a user's assigned list (or perhaps the other way around: add / remove assigned users from a vehicle's assigned user list).
The XACML rule itself will not change. If the supervisor adds 20 more cars to the employee's list (maintained in the application-level database), then the PDP will be able to use that information via the PIP and access will be granted or denied accordingly.
The key benefit of XACML is that you could add a second rule that would state a supervisor can see the cars he/she is assigned to (the normal rule) as well as the cars assigned to his/her subordinates (a new proxy-delegate rule).
This diagram, taken from the Axiomatics blog, summarizes the XACML flow:
HTH, let me know if you have further questions. You can download ALFA here and you can watch tutorials here.

Related

Django role based permissions

I'm developing a huge application in django and I need a permission system and I assume that the native user/group permission within django is not sufficient. Here my needs:
The application will be available through multiple departments. In each department there will be nearly the same actions. But maybe an user will be allowed to add a new team member in department A and in department B he is only allowed to view the team list and in the other departments he has no access at all.
I though using a RBAC system would be most appropriate. Roles must also be inheritable, stored in a model an managable through an interface. Any good ideas or suggestions? Regards
What you are looking for is called abac aka Attribute-Based Access Control. It's an evolution of RBAC as an access control model. In RBAC, you define access control in terms of roles, groups, and potentially permissions. You then have to write code within your application to make sense of the roles and groups. This is called identity-centric access control.
In ABAC, there are 2 new elements:
attributes which are a generalization of groups and roles. Attributes are a key-value pair that can describe anyone and anything. For instance, department, member, and action are all attributes.
policies tie attributes together to determine whether access should be granted or denied. Policies are a human-friendly way of expressing authorization. Rather than write custom code in your app, you write a policy that can be centrally managed and reused across apps, databases and APIs.
There are a couple of ABAC languages such as xacml and alfa. Using ALFA, I could write the following policy:
A user will be allowed to add a new team member in department A
In department B he is only allowed to view the team list
In the other departments he has no access at all.
Roles must also be inheritable, stored in a model an managable through an interface.
policyset appAccess{
apply firstApplicable
policy members{
target clause object = "member"
apply firstApplicable
/**
* A user can add a member to a department if they are a manager and if they are assigned to that department.
*/
rule addMember{
target clause role == "manager" and action == "add"
permit
condition user.department == target.department
}
}
}
One of the key benefits of ABAC is that you can develop as many policies as you like, audit them, share them, and not have to touch your application code at all because you end up externalizing authorization.
There are several engines / projects that implement ABAC such as:
AuthZForce (a Java library for XACML authorization)
Axiomatics Policy Server (commercial product - disclaimer: I work there)
AT&T XACML
There are two components to this question:
First, role management. Roles can be achieved through group membership, i.e. departmentA_addMember & departmentB_listMembers. These Groups would have corresponding permissions attached, e.g. "Member | Add" and "Member | View". A department in this context may have more resources included, that require separate permissions. Django allows to extend Objects with custom Permissions.
Second, inheritance. Do I understand you want to have individual Groups being member of other groups? Then this is something Django would require you to implement yourself.
However, should you be looking for a really more complex authentication solution, it may be worthwhile to integrate with 3rd party services through, e.g. django-allauth. There are sure more/other solutions, just to throw in one name.

Relationships and ACL in Baqend

I'm trying to figure out if this is possible with baqend, or even the correct approach to begin with.
I have a bunch of users, using the default user account system that comes with Baqend.
Some of these users will be administrators of a company. A company will have somewhere between 1 and 5 users who are administrators.
There is a separate data class that contains a record for the company and an array of users who are the administrators.
Like this:
{
id: "/db/Companies/123-456-789",
name: "Test Co",
admins: [
{ id: "/db/Users/10", name: "Joe Schmo" },
{ id: "/db/Users/11", name: "Kate Skate" },
{ id: "/db/Users/12", name: "Johny Begood" }
]
}
What is the approach to ensure that only users 10, 11, and 12 can modify the contents of the admins array and whatever else is contained in /db/Companies/123-456-789 ?
Is it as simple as inserting the additional admin's info into the array and also adding that person to the ACL of /db/Companies/123-456-789 at the same time or right after?
Also what is the way to remove a persons ACL? I see how to set it here: https://www.baqend.com/guide/topics/user-management/#permissions but how do we do remove or delete? And what is the difference between explicitly denying that user in the ACL vs that user simply not existing (and I guess by default being denied? Assuming the entire collection is set to NOT be public in the first place).
For our use, just because an administrator leaves does not mean he leaves OUR APP, he might go work for another customer who uses our app and his user account should remain valid, but with no more access to the company record.
I think you already have it quite right: you can add administrators to a company by adding them to the admins array and by explicitly allowing them read and write access in the ACLs. To remove admin rights, you can simply remove the explicit allow rules for the soon-to-be-ex admin.
In Baqend, permissions are enforced like this:
superusers are always allowed.
explicitly denied users and roles are always denied.
if there is no allow rule for a record, access is public. As soon as there is at least one allow rule, only allowed users are granted access.
Since every record is public unless there is at least one allow rule, your record will be protected when you allow access to the administrators. However, it will be public again as soon as you remove the last administrator from the access ruleset. Therefore, it's probably a good idea to always explicitly allow write access to your Baqend app admin, so that there is always at least one allow rule.
let me try to explain how exactly ACLs in Baqend work.
TL;DR
To secure your object /db/Companies/123-456-789 you can simply add an allow rule for each of your three user ids (/db/Users/10. /db/Users/11, /db/Users/12) to the object acls of your company object like this:
db.Companies.load("/db/Companies/123-456-789").then(function(company) {
company.allowWriteAccess("/db/Users/10");
company.allowWriteAccess("/db/Users/11");
company.allowWriteAccess("/db/Users/12");
return company.save();
})
This ensures that only these users can edit the company object. Notably, this list of rules is independent of the list of admins contained in your company object. To revoke the write access of a user, you can use deleteWriteAccess in the same way we used allowWriteAccess before.
This means your users can leave a Company easily without leaving your app.
I hope this answers your question. Because ACLs are complex I will try to explain the general approach in more detail now.
How ACLs Work
On which level can access be controlled?
There are two levels to control access to your data:
On table level (so-called Schema ACLs)
On object level (so-called Object ACLs)
Schema ACLs define who is allowed access to the table in general. For example, you could define that the User table is not readable for the public by granting read access only to the admin:
allowReadAccess("/db/Role/admin") // Schema ACLs can only be set by the admin
You can define rules for reading, updating, inserting and querying on the table separately.
Object ACLs defines access on the lower level. You can use it to deny access to a specific object. For example, you could define that only the user itself can update its own User object, like this:
allowWriteAccess("<userId>")
For objects, you can define rules for reading and writing separately.
Who has access now (how are permission evaluated)?
In order to access an object, a user needs to have general permission to access the table (Schema ACLs) and also permission to access the object itself (Object ACLs). This means the Schema ACLs are evaluated first if they grant you access, the Object ACLs are evaluated as well.
Which rules can I define?
There are two types of rules that can be defined to allow or deny access:
Allow Rules define who has access in general. These rules are checked first. If you do not define allow rules, everyone has general access.
Deny Rules defines who is denied access (even if the user was allowed by an allow rule). These rules are checked after the allow rules.
Take a look at the JS API for ACLs for the actual method documentation.
These separate rules can be tricky at the start but they are really powerful. Let's do some examples. How can I use these rules to ...
Deny access for everyone: --> Set the only allow rule for admin
Allow access for logged-in users but not for some guy Peter (like when you block someone is a chat application): --> Set an allow rule for the loggedin role and a deny rule for Peter.
Only allow access from backend code modules: --> Set an allow rule for the node role (see below for the explanation of Roles).
Who can I grant or deny access?
There are two entities you can use in your allow and deny rules:
Users from the predefined User table can be granted or denied access
Groups of Users defined in the predefined Role table can be granted or denied access
The predefined roles admin, loggedin (represents all logged-in users) and node (represents backend code modules that access the database)
What is the default access for my tables?
Tables and objects are publically accessible by default if not configured otherwise.
What about attribute-level ACLs
There are no attribute level ACLs in Baqend. This means when you have a User object with a private email address and a public name you can only make the object private or public.
The solution for this is to use two objects, one for the private information and one for the public information and then link the two. For the User, this would mean you make the actual User object private and define a new Profile table where you keep the public user information.
While this solution is more work when defining your schema, there are good reasons why Baqend does not support attribute-level ACLs. Without going into too much detail:
Better caching. Attribute-level ACLs would severely limit how we can cache and therefore accelerate your database requests.
Expensive evaluation. Attribute-level ACLs are much harder to evaluate and therefore slow down database access. Object-level ACLs, on the other hand, can be pushed down to our database system and are evaluated very efficiently.
Something missing
I hope these explanations help to understand the ACL system better. If there is something missing here, just comment and I will add it.

What is the difference between roles, affiliations and attributes?

I am adding users to my ca-server's config file. I want to know what are the differences between roles, affiliations and attributes?
In tutorials I can see that roles is assigned to one of these: "client,user,peer,validator,auditor,ca". I want to know can be use some other role? If a user is assigned "client" role then can he have a validating role running with that identity. What's the difference between "client" and "user"? What's the difference between "peer" and "validator"? And also what is auditor specifically.
I think affiliations are used to categorize identities. Is that right?
Identity type can be any arbitrary string as far as Fabric CA is concerned.
I think of affiliations as hierarchical tags. Each identity can be tagged (affiliated) to (with) one affiliation in the hierarchy. When an identity is associated with an affiliation, it is affiliated with that and all the child affiliations.
1) Affiliations are currently used during registration and revocation. You can read more about registration/revocation at https://hyperledger-fabric-ca.readthedocs.io/en/latest/users-guide.html
Attributes are key-value pairs that can be associated with an identity. hf.Registrar.Roles, hf.Registrar.DelegateRoles, hf.Revoker, and hf.IntermediateCA are currently in use with in Fabric CA server. These are used to make access control decisions. Currently attributes are not used in any other Fabric components, afaik.
For example, if an identity with “hf.Registrar.Roles” attribute set to “peer,app,user” and affiliated to org1.dept1, can register identities of type peer, app, and user, (but not orderer) that are affiliated with org1.dept1 (but not identities affiliated with org1 or org1.dept2)
I hope this is helps

How to realize modifying call in REST API

Assume you have some resource behind a REST API. This resource could well be modified using the usual HTTP verbs PUT or PATCH. But let's assume the server behind the API has to check some prerequisites to decide if the modification on the resource can be made or not (e.g. withdraw an amount from a bank account).
In this case there is no use in using POST (because we do not want to add a new resource), nor PUT or PATCH, because only the server knows about the new value of the resources' modified attribute, if he will allow the requested modification at all. In the above example the account's new balance would have to be computed on the server side like so : balance = balance - amount, and to my knowledge all the client can do with PUT or PATCH is to send the already modified resource (the account) or atttribute of that resource (the accounts' balance).
Am I then right in assuming that in this case the API designer has to provide a parameter (e.g. .../account?withdraw=amount) with the URL pointing to the resource ? What would be the correct HTTP verb for this operation ?
there is no use in using POST (because we do not want to add a new resource)
You do. A monetary exchange can be expressed in a transaction, hence: you're creating a new transaction.
So simply perform a POST with the transaction details to a /transaction endpoint.
You certainly don't want to allow users to PUT their new account balance, as that would require atomicity over HTTP, which is all REST stands against: the client would have to know the pre-transaction balance, and make sure in some way no transaction will be carried out before theirs arrives.

Find files accessible outside of my organization

In the Drive.Files.List I can, using the 'q' parameter, get all files a user can read/write or own. I would like to be able to use regular expression in the query value. For example set q to be "not '.+#my-org.com' in writers".
Is such a query already supported?
Do I have another way (except invoking Drive.Permissions.List for each and every file in my Drive) to get this information from?
Seems the only account level drive API is part of the report API - activities list. This API (and admin console - audit - drive) section is only supported in the unlimited license. Still haven't found the proper API get the drive state (list all files metadata in the account, permissions etc.) seems that the state can only be inferred from analyzing the relevant activity events assuming the activity is not being evicted after a predefined period of time.
My conclusion, at the moment, is that there is no "root" directory at the account level. "root" is only with respect to the logged in user.
I would be more than happy to be proved wrong.
Uri