Electronic Medical Records (EMR) systems require complex authorization rules. Healthcare providers need precisely controlled access to patient data based on multiple factors: roles, care relationships, and time-sensitive conditions like shift times.
In this post, we'll explore how Oso's modeling language, Polar, elegantly handles these complex requirements. We’ll also give you details about a complete web app that integrates a reasonable set of EMR requirements that you can both run and examine yourself.
The Challenge of EMR Authorization
A minimal viable product (MVP) for an EMR system might require:
- Medical staff to have full access to their current patients' records
- Patients to view specific portions of their own medical records
- Administrative staff to manage visits and user accounts
If you're building this as a SaaS application, you must also ensure each tenant can access only their own data.
To make things a little more robust, you might also consider:
- Restricting medical staff access to patient records to their active shift hours
- Supporting specialized roles (nurses, specialists) with different levels of access to medical records
It’s easy to see that all of these overlapping requirements create significant complexity.
Why RBAC Isn't Enough
The easiest approach to managing authorization yourself is to implement Role-Based Access Control (RBAC)––however, RBAC alone proves insufficient for complex healthcare scenarios.
Consider managing doctor-patient relationships: How would you handle care relationships using only roles? Creating a role for each patient-doctor relationship or vice versa becomes unwieldy. What happens when appointments change providers or get canceled? RBAC's limitations become apparent when dealing with these kinds of dynamic and realistic relationships.
Fine-Grained Authorization
Polar's flexibility allows you to combine multiple authorization approaches: RBAC, Relationship-Based Access Control (ReBAC), Attribute-Based Access Control (ABAC), and others. To prove this, let's examine a simplified EMR policy that addresses our requirements.
First, we'll define the organization structure for a multi-tenant SaaS application:
actor User {}
resource Organization {
# Roles which users may have within an organization
roles = [
"medical_staff",
"administrative_staff",
"patient"
];
# Actions which users may take on an organization
permissions = ["read", "schedule_appointment"];
# RBAC
"read" if "medical_staff" or "administrative_staff";
# EMR permissions
"schedule_appointment" if "administrative_staff";
}
This establishes three roles (medical staff, administrative staff, and patients) and allows administrative staff to schedule appointments.
Next, let's model appointments:
resource Appointment {
permissions = ["read", "cancel", "complete"];
relations = {
org: Organization,
medical_staff: User,
patient: User,
};
"read" if "read" on "org";
"read" if "patient";
"complete" if "medical_staff"
and appointment_status(resource, "scheduled");
"cancel" if "administrative_staff" on "org"
and appointment_status(resource, "scheduled");
}
Here we see Polar's expressive power through:
- Relations: To make ReBAC simple, Polar's offers shorthand rules using
relations
. From here, it’s simple to write rules that depend on relationships between entities. - Attributes: We can use an appointment’s status in our authorization data (
appointment_status(resource, "scheduled")
) to allow different permissions based on an attribute of the appointment, a.k.a ABAC. This will let us ultimately ensure we maintain a consistent set of state transitions. - Complex rule combinations: We can freely mix together multiple approaches. For example, a user can
complete
an appointment only if they are the medical staff for it (ReBAC) and the appointment has the”scheduled”
status.
These features would be cumbersome to implement with RBAC alone, but Polar expresses them naturally.
Complete Reference Implementation
To see these requirements in action, including advanced features like field-level authorization, check out our Sample EMR App. It uses:
- Node.js with React server components
- PostgreSQL with local authorization
Find the complete implementation on GitHub.
Future Possibilities
While our reference implementation demonstrates core EMR authorization patterns, real-world healthcare systems often require even more sophisticated access controls. Consider shift-based access management: you could sync staff schedules with Oso Cloud to automatically grant and revoke record access based on working hours. This is just one example of how Oso's flexible architecture can adapt to evolving healthcare requirements.
Healthcare organizations face increasing pressure to balance data accessibility with privacy and compliance. Oso's Polar language provides the building blocks needed to meet these challenges. Its declarative syntax lets you express complex authorization rules clearly, while its composable nature means you can extend the system without rewriting existing logic.
By centralizing authorization in maintainable Polar rules, development teams can focus on delivering new EMR features with confidence that access controls remain robust. Whether you're implementing basic RBAC permissions or need the complexity of ReBAC and ABAC, Oso gives you the tools to maintain security without sacrificing development velocity.
Have questions about implementing Oso in your EMR application? Join our community Slack or schedule a call with our team.