We have another exciting endeavour in OpenMRS Core! We are planning to do a revamp of our authentication and authorization framework. It’s a complex topic and we are hoping to do it in an informed way thus asking developers and implementers for input.
Currently OpenMRS Core supports only basic authentication. In addition to that there’s the OAuth module that enables the use of external authentication providers. We are considering upgrading to Spring Security and thus opening up for different authentication methods from within core.
The more impactful and more complex change that we are planning is around authorization. Currently OpenMRS uses permissions and roles to limit access to certain operations for users. There’s also the data filter module that tries to add another layer of access control based on a location that a user chooses when logging in.
What’s currently possible?
Currently, it’s possible to enforce rules such as:
Registration clerk can manage ALL patients’ visits, but has no access to ANY patients’ encounters and observations.
Dr. Smith can only view/edit ALL patients assigned to a certain location. (with data filter module)
What are we aiming for?
We would like to provide a more granular access control. There are different approaches to this complex problem so we need to determine one that suits needs for majority of implementers thus this initial thread in hope to hear about all your needs that are not addressed by the currently available solutions.
Here are some examples of attribute and relationship based access control rules that we are aiming for to be possible:
Dr. Smith can view Patient A’s encounters and observations because Dr. Smith is a member of the Cardiology Team, and the Cardiology Team is the treating group for Patient A.
Dr. Brown is examining Patient A and can only view Patient A’s encounters and observations until examination is completed (e.g. conducted MRI, visit completed).
Mrs. Taylor is doing laboratory tests and can only view/enter encounters and observations of specific type.
Evaluation of Spring ACL
Spring Security provides a feature called ACL, which is a domain-object-level access control (e.g., “User A has READ access to Record 123”).
While that sounds exactly like what OpenMRS needs, the way Spring ACL implements this makes it dangerous for our domain. It creates dedicated tables to map permissions. If you have thousands of patients with hundreds of individual records (lab results, notes, prescriptions), and hundreds of staff members, Spring ACL will generate millions of rows just to map who can see what. Querying these massively bloated tables on every single data fetch introduces severe latency. Moreover it is static so e.g. if a nurse’s shift ends, or a doctor is temporarily assigned to a new ward, updating thousands of individual ACL rows in the database to reflect that temporary reality is a nightmare.
The Proposed Technical Path
The currently considred proposal is to continue with our RBAC permissions and add Attribute and Relationship Based Access Control via Spring Security’s method annotations like:
@PreAuthorize("@openmrsSecurity.isAuthorized(authentication, #patientId)") to handle the logic dynamically in code.
@PostAuthorize for filtering of results and @AuthorizeReturnObject to proxy returned objects and limit access on their fields.
For performance reasons, we should also provide a mechanism to adjust DB queries similar to what the data filter module does so that not all checks are done in code, but also at the DB level.
This change will not happen in one release. We aim to provide a framework to add these more complex access rules and start refactoring code to be able to apply those rules in different places.
It is also essential for an implementation to be able to adjust rules or disable them completely depending on needs.
How can you help?
First of all its important to identify different access control rules that you see relevant in your setup. A list of examples as listed above.
We are also looking for alternative ideas or frameworks that we could use to enforce rules.
Once we identify the technical solution and business rules, we would love help from developers to introduce changes in core and modules.