O3: Privileges Plan?

I’ve been hearing questions like this: (These are from reps of 4 different orgs)

  • What kinds of privileges will be possible with OpenMRS3?
  • Has anyone implemented privilege based display/hiding of links/page elements in o3? Something like userHasAccess(a_requiredPrivilege, ?) ?
  • Our customer requires that every single widget needs permissions
  • How does 3.x handle viewing permissions, e.g. only allow limited version of Patient Summary for someone in Lab? eg Putting a **** over certain info? eg if you don’t want a Social Worker to see Diagnosis History, or don’t want an Archivist to see “HIV +”?

Can we talk here about how are folks planning to manage privileges for 3.x?

Back in October 2021, @florianrappl (Mekom) demo’d on a 3.x squad call that he had added a privilege layer to extensions. Mentioned this should work both online and offline:

I’m also wondering: Does this config only hide the information in the UI? Or does it entirely restrict user access to the information? I remember working on a previous system where “hiding” stuff in the UI was not a valid solution, because a knowledgeable user could easily bypass this.



Further context...

What OpenMRS has historically supported:

CCing: @ibacher @mksrom @mksd @jdick @burke @dkayiwa @mseaton @zacbutko @alaboso

Thanks @grace, important conversation here about RBAC in general.

Let us distinguish two areas:

  1. RBAC to features - this is a frontend concern.
  2. RBAC to data - this is a backend concern.

Those points

touch RBAC to features, and as you recalled there is an architecture in place in O3 (with this userHasAccess introduced by @florianrappl :+1:) and we should just learn to leverage it at every corner of the app.

Let’s imagine that we are designing a new appointments widget for the patient chart. When the dev sets up the code for it they should do two things:

  1. Shield it with an O3-privilege, such as maybe userHasAccess("o3.view.appointments.widget", ..).
  2. Liaise with the platform team to ensure that this o3.view.appointments.widget privilege is indeed defined in our backend OpenMRS config for O3.

Cc :warning: @zacbutko and @vasharma05 :point_up:


RBAC to data is a totally different story and is strictly speaking not an O3 question, it’s an OpenMRS question in general. That’s in relation to this point:

How does 3.x handle viewing permissions, e.g. only allow limited version of Patient Summary for someone in Lab? eg Putting a **** over certain info? eg if you don’t want a Social Worker to see Diagnosis History, or don’t want an Archivist to see “HIV +”?

This is a scope creep and cannot be addressed quickly, same goes for location-based access which is also about data.

At @MekomSolutions we have handled RBAC to data through the Data Filter module, that basically adds an RBAC layer for data to Core, until RBAC to data would perhaps one day be fully supported in Core natively.

Note that Data Filter is only about viewing (or not viewing) data.

1 Like

Hi @mksd @grace! AFAIR from the meeting in which this role-based access was introduced, it was only meant to hide the particular widget from the UI, i.e. it wasn’t rendered in the application. I and @zacbutko can have a talk with @florianrappl about how this was implemented in the first place and what are the changes needed in this. Will this be a good step to move ahead?

@mksd is 100% right. There is nothing to do @vasharma05 - a frontend system can never protect somebody from accessing some data. It’s the job of the backend to actually restrict the data access.

The privileges feature of the UI really just does not render (or in most cases) load the relevant widget. Usually, this also prevents the backend call from being made, but independent of that the backend call should never succeed (or not be relevant w.r.t. the given privileges).

TL;DR: Actual protection can only be done via the backend - the frontend’s job is to be optimized and only show to the user what the user can access.

3 Likes

Totally got your point @florianrappl! Thanks alot!

There’s nothing to do in the sense that the ESM framework has a mechanism for handling this display hiding. However, there are, however, at least three things that need to be done in this area:

  1. We need to ensure that privilege checks are correctly added to frontend apps where appropriate. Currently only three places in the frontend use this utility: the implementer tools, the attachments view, and the RefApp links in the home page app. (OHRI apps also do not seem to leverage this functionality).
  2. At a framework level, an implementer should be able to configure the privileges needed to access an extension via the configuration schema.
  3. We’ve traditionally had separate permissions to grant users access to view data even if they don’t have access to modify the data. In general, it would be good if we had slightly more fine-grained permissions at the app level so that, e.g., the extension renders as long as the user has the “view” permission, but any actions only render if the user has the “add / edit / delete” or “manage” permission. Right now, only the attachments part seems to implement this model.

Of course, the backend will still block users without appropriate permissions from submitting data but it’s a little weird that the user can bring up a screen and fill it all in only to have the request rejected.

1 Like

Thanks for bringing this up, @grace. OpenMRS frontend and backend would benefit greatly from a thoughtful approach to privileging. We started with privileges & roles, where privileges controlled access to specific API methods and roles allowed the privileges to be grouped for easier assignment/management. This worked well initially, but ran into a some problems that we’re likely to exacerbate or recreate on the frontend if we’re not careful:

  1. As the number of privileges grow, they become difficult for admins to manage. Roles can help assign groups of privileges, but admins can’t easily know which privileges are needed for a workflow. This led OpenMRS 2.x to a hacky approach of granting all backend privileges to users and managing feature-level privileges in the frontend, which isn’t a viable approach for OpenMRS 3.
    • If frontend features aren’t behaving as expected for a user because of a privileging issue, how does an admin troubleshoot the problem?
    • Can we come up with a way of more effectively communicating/documenting the set of privileges needed or used by a module/widget. In the past, we considered the idea of “privilege groups” as a way to define a collection of privileges needed for a feature/module, but this never got implemented.
  2. Roles (groups of privileges) are often misinterpreted or created as organizational roles (“Doctor” or “Nurse”) when they are really intended to be application roles (e.g., “Can write orders” or “Can view nursing dashboard”) – i.e., application roles should focus on what a user can do with the application and not their job title.
    • The UserGroup feature could help us in separating organizational roles from application roles.
1 Like

For me I understand that customizability is important, but would hesitate to say that deciding widget permissions should be left to implementors. I think security of data is one area where we should be prescriptive as a platform. That is, we should put a lot of thought into what the permissions are and what they mean, and a widget should know where it fits in that data privacy / security paradigm. Totally agree with @florianrappl that this is only part of the solution, and backend also needs to agree to this permission schema together. However, if both parts are moving it can be hard to know what is actually happening and what is secure / private.

I think the solution for customizing the implementation then comes from assigning permissions to roles. Once we have.a stable idea of what permission does what, we can set it up so that my Nurse has different permissions than her Nurse. This way customizability and security can both win.

To @burke 's point, we should have good transparency in minimally docstrings and optionally docs or UI that shows clearly the permissions that each workflow depends on. Access issues should give clear alerts as to what permission is missing.

To @burke 's other point, I can see how permission groups could be useful

1 Like

Adding more to the history, we also created this module: Privilege Helper Module - Documentation - OpenMRS Wiki :slight_smile:

1 Like