Background
The other comments and answers as well as your post point you in the right direction. You need a framework that is flexible enough to address your current authorization needs as well as future ones. That framework (or model) is indeed Attribute Based Access Control (abac). It's also known as dynamic authorization management and policy-based access control. Gartner, Kuppinger Cole, and Axiomatics (where I work) all have written extensively on the topic:
That said, given your requirements, ABAC only solves half the equation: the authorization policies and logic. It does not solve the attribute management. You still need to think about metadata or attributes of your users or resources (the projects in your case) that will drive the authorization policies you have.
Your use cases
Read-only users (i.e. some users may only log in and view items)
You would need to define a persona or role that you can assign to users to denote they are read-only. Maybe it's the baseline role in your system. Maybe it's the absence of the role but the fact you successfully authenticated.
Only a few users may change global settings (like managing
integrations, billing information etc.)
What makes these users special? A role e.g. "administrator" or "superuser"? You need to define that and you need a process to assign that role to users.
Only a few users may change settings for one of our three product modules
Same story as above.
For each created resource (e.g. a project, a team, ...), only the project members / team members may change the resource.
Like you said yourself, this is spot-on ABAC. You would need to write a simple policy (or rule - the words are interchangeable) that states (pseudocode - you could use ALFA too):
A user with role=="..." can do action=="edit" on object of type=="record" if record.assignedProject == user.assignedProject.
By default, all users may view all projects, but it should be possible to "hide" projects so that only the project members may view the hidden project.
See below for an example in ALFA
Enforcing ABAC
Thinking policies and use cases is great but you also need to think about the enforcement of the decisions. ABAC has a notion of a Policy Enforcement Point (PEP) and Policy Decision Point (PDP). The PEP is where the rubber hits the road: what are you protecting? A web portal? A business process? An API? Either way you need to have a PEP or interceptor in place capable of applying the right authorization. Here's what the architecture looks like from a high-level:
![Axiomatics Attribute Based Access Control Architecture & Flow](../../images/3833728154.webp)
Sample ALFA Code
ALFA, the abbreviated language for authorization is one of the two main standards for authorization along with XACML. ALFA is a simplified notation of the same model XACML follows (policy set, policy, rule). I wrote some samples based on your use case:
namespace com.axiomatics.examples{
/**
* Projects
*/
policyset projects{
target clause objectType == "project"
apply firstApplicable
/**
* View Projects
*/
policy viewProjects{
target clause action == "view"
apply firstApplicable
/** Anyone can view a project */
rule viewVisibleProjects{
target clause project.hidden == false
permit
}
/**
* Only members can view hidden projects - it should be possible to "hide" projects so that only the project members may view the hidden project.
*/
rule viewHiddenProjects{
target clause project.hidden == true
permit
condition stringAtLeastOneMemberOf(user.name, project.members)
}
}
}
/**
* For each created resource (e.g. a project, a team, ...), only the project members / team members may change the resource.
*/
policyset records{
target clause objectType == "record"
apply firstApplicable
/**
* Edit records
*/
policy editRecord{
target clause action == "edit"
apply firstApplicable
/** Project members can edit a record in their project */
rule viewVisibleProjects{
permit
condition record.project == user.assignedProject
}
}
}
/**
* Global settings - Only a few users may change global settings (like managing integrations, billing information etc.)
*/
policy globalSettings{
target clause objectType == "global settings"
apply firstApplicable
/**
* Administrators can view and change global settings
*/
rule administrators{
target clause user.role=="administrator"
clause action=="view" or action=="edit"
permit
}
}
}
Implementations
There are several good implementations of ABAC out there:
- Open-source
- AuthZForce provides you with a XACML-conformant authorization engine
- Open Policy Agent (OPA) provides you with a REGO-conformant authorization engine. OPA focuses on infrastructure (Kubernetes, Istio...)
- Commercial
- Axiomatics (where I work) is possibly the oldest company in the list. We've been implementing ABAC since 2006. Everything's based on XACML and ALFA and we can apply authorization to portals, APIs, and databases.
- Oracle, IBM, and other large vendors also have their own solutions.