An ABAC implementation is more complex than ACL/RBAC. Some frameworks even give you bits of infrastructure to deal with the latter. If the people and assets can be grouped under a relatively small and fixed number of roles/categories then it's probably best to stick with ACL/RBAC. If permissions differ vastly from person to person then ABAC could provide a better and more flexible solution.
If you choose to go down the ABAC path the first thing you need to do is spend some time reading and understanding the XACML standard. The examples provided in the document use XACML compatible syntax and they're a bit tough to chew at first. I'm guessing you don't want to implement a standard compatible solution so you only need the general ideas from it.
Concepts
XACML revolves around 4 concepts and their attributes: subjects, actions, resources and environment. There are a few more, but these are the most important. Everything else is built on top of them. If I were to make a sentence with these concepts it could be something along the lines of: subjects perform actions on resources in a certain environment. Applying this to your scenario would translate into something like:
- Leslie opens the price manager web page.
- Leslie creates a travel price using the price manager web page.
Attribute collection
The first thing we need to do is gather the relevant attributes of the concepts stated above. Ideally, you should not be assigning any specific attributes as XACML tries to be unobtrusive and rely only upon what the system naturally provides. And so we have:
Subject
Any actor, be it a person or a service, in your system. Our subject is Leslie. What attributes are required to uniquely identify Leslie? Probably some of the following: first name
, last name
, e-mail
, ssn
, company id
, position(s)
.
Action
Any action performed by the subjects. Can be the standard CRUD operations or something more complex. Our actions are open/view
and create
. The attributes for these actions can be different based on web application framework you're using. We'll talk more about this when we get to the resource.
Resource
Pretty self explanatory. Our resources are the price manager page
, travel prices
and the newly created price
. There could be more, if you really want to. You may want to hide actions that the users can't perform. Eg. the create price button
can be a resource that can be shown/hidden based on whether the user has permissions to create prices. Since the only way for a user to see a list of prices could be through this page it would probably be a good idea to enforce authorization at this level rather than further down the stack.
Access to resources is the most complicated to implement, especially on the ones that come from a database. The finer grained option is row-level security. Some databases have a certain degree of support for it. Some XACML implementers have gone as far as creating a SQL superset. This really depends on your authorization needs but the one thing you don't want to do is pull everything from a table and then decide what to show. You could group resources by permission sets, abstract them behind an API and enforce authorization at the API endpoints.
Environment
I can't properly define it (XACML also doesn't have a proper definition) but let's say it's the "bubble" in which all this happens. This includes: web application
, web server
, operating system
, browser
, office
. You could extract attributes like: ip address
, time of day
, user locale
, user agent
, operating system version
. You can use these to even block user access from environments that are not supported by your application (eg. old browsers, old operating systems, computers outside of your network, access outside business hours).
Authorization request
Once we've gathered all the necessary attributes we bunch them up in an authorization request and forward it to an entity that can make authorization decisions based on the values of these attributes. In XACML lingua the place where you collect these attributes and enforce the decisions made upon then is called a policy enforcement point (PEP) and the point making decisions is called a policy decision point (PDP). The locations from which attribute values are obtained are called policy information points (PIP). PEPs, PDPs and PIPs can be a part of your application of they can be external systems. You can find a diagram of how they communicate with each other in the XACML standard.
Decision process
The decision making process is based on rules. Rules can be grouped into policies which can be further grouped into policy sets. Each of these has a target. The target is used to decide if any of the rules apply to the authorization request. Think of it as a filter. The target contains conditions built using attribute names and values. For example, the rules for your application could be grouped into something like:
Web application (policy set)
|-- target: application-name == "Web application"
`-- Version 1.0 (policy set)
|-- target: application-version == "1.0"
`-- View price manager (policy)
|-- target: web-page-name == "price manager" && action-name == "view"
`-- Leslie can view the prices manager (rule)
|-- target: subject-name == "Leslie"
`-- permission: allow
The PDP will match everything in the above set against the attribute values in the authorization request. What happens if there aren't rules that match it depends on the implementation of your PDP. Once the PDP has made a decision (allow
, deny
or not-applicable
) it sends it back to the PEP which acts upon it by granting or denying access to the resource. Along with the response the PDP can send a list of obligations
and advices
that the PEP must or should fulfill in the enforcement process. Depending on how the rules are stored (text files or database) an administrator can use a standard text editor or a custom editing application to change these as he/she sees fit. Revoking Leslie's access to the prices manager resumes to simply changing permission from allow
to deny
, granted the PEP does its job.
Enforcement
This is highly dependent on your technology stack. Some web frameworks have natural enforcement points (eg. ASP.NET MVC has attribute filters). Your business layers might have to define such enforcement points. I found it easier to apply enforcement at service (think microservices) endpoints or UI level.
Other benefits
A nice side effect of implementing this is that you end up with a fairly rich audit trail which can be used for other purposes.