Question

I'm designing a enterprise infrastructure monitoring application which has customized needs of access control, beyond roles and authorities.

The architecture include multiple nodes of REST API being load balanced, an angular client and an authorization server based on OAuth 2.0 using JWT.

These Rest API nodes are generic and can be run using different configuration properties which will make them work for a different infrastructure which are similar in nature but are separated on the business level. You can think of it as monitoring two different data-centers which are similar in nature but are managed by different group of people due to the scale of infrastructure.

The REST APIs can be run for any of the data-centers by changing some command line arguments.

Then there is an angular client which is made in such a fashion that it can access both of the data-centers' REST API (There is a master dropdown on the top header changing which will basically change the base URL for API hits and hence the datacenter) based on the authorities that signed in user have.

Now the problem part is access control using OAuth 2.0. There are three levels of access control required

  • Level 1: Datacenter level
  • Level 2: Dashboard level
  • Level 3: Action (on a Dashboard) Level

So the use cases may include many situations like:

  1. A user having access to a datacenter 1 but not to datacenter 2
  2. A user having access to a particular datacenter but not to a dashboard in that datacenter
  3. A user having access to a particular dashboard in datacenter 1 but not in datacenter 2
  4. A user having read access to a particular dashboard but not able to modify anything on that dashboard on datacenter 1 but can modify the same things for datacenter 2

To handle all these scenarios, the angular client will require every user's scope of access so that it can choose to show/hide and restrict access to a particular dashboard or action.

Now the question comes is that many of these access scopes are associated with a web client (angular client in our case) and not directly related to the REST API i.e. many of the authorities that I will be defining will be helpful for the angular client but won't make any sense to any other client (for ex. a python client).

How can I handle such client specific scenarios on the authorization server. Am I thinking in the right direction or do I need to change my perspective?

Was it helpful?

Solution

here's a list of few things worth pondering:

  • Resources are responsible for their own access control. The types of clients and use cases can inform how you want to break down or group together permissions into roles and similar, but ultimately those should all be things whose semantic is understood by the resource- and the clients only choose what to ask for from a common framework (or, if you aren't in a delegated case, you choose what privileges to assign to the clients and users)
  • The client never really restricts access to anything. You can optimize the experience and hide options you already know aren't viable to the current user, but that act in itself is not access control. A rogue client using a stole token might bypass all your frontend measures. The resource is still responsible for enforcing access.
  • Access control is a matter between the authorization server and the resource. Unless you on both resource and clients, plan to forever own both ends, and are ok with developing them in lockstep, all severe limitations, you should expect the resource to be the sole and ultimate arbiter of what's the semantic and access control policy of the attributes in your tokens. For that reason, clients should never look inside access tokens not meant for them (more details here). If you want clients to have visibility on some of that info for UX optimization purposes (see above), return an id_token and ensure that the info you want to share with the clients is there.

OTHER TIPS

To add-on to this answer, the Authorization Server (AS) would need some way to model these Access Policies (i.e., "User 1 can access Dashboard on DC1 but not DC2", etc.) somehow. In my experience, using Graphs and Graph databases for this purpose can help a lot. These could of course be modeled otherwise, the point being that the rules need to be expressed somewhere somehow, and understandable by the Authorization Server.

Once modeled, the AS can evaluate access requests from the Client App for the given Scope (e.g., "Write", "Read", etc...) using these rules, and respond with "Grant" or "Deny".

The client App would then just need to deal with the response, in particular the "Deny".

Licensed under: CC-BY-SA with attribution
scroll top