Access Control

Healthcare RBAC: building access control that holds up

Most apps get away with "admin" and "user." Healthcare software doesn't get that luxury. A physician, an attorney, and a billing admin need three very different views into the same system.

I built the permission system for Synectus Medico around six distinct roles. Here's what actually made it hold up in production, not just in a design doc.

Design My Permission Model
// the six-role model

Modeling the actual clinical roles

Six roles is not a magic number, it's what mapped onto the actual people using Medico. Your platform might need five, or eight.

Super Admin

Sees across every clinic on the platform. Creates clinics, manages platform-wide settings, sends broadcast notifications.

Clinic Admin

Runs one clinic. Manages staff accounts, configures settings, has billing and operations visibility for that clinic only.

Executive

A clinic-level leadership view: cross-physician analytics and revenue reporting, without account-management permissions.

Physician

Sees their own patients, their own exam queue, their own report drafts. Not another physician's caseload in the same clinic.

Attorney

Sees only their own clients' cases: billing status, LOP documents, case timeline. Not internal notes, not other attorneys' clients.

Doctor

Referring physicians and sub-clinic doctors. A narrower view, usually limited to patients they've referred.

// two layers

Route-level and component-level enforcement

Route-level protection

Certain pages are only accessible to certain roles. Route protection checks the user's role from their JWT before rendering anything.

Component-level permission keys

Every interactive element has a permission key. Components lacking a required key are removed from the DOM entirely, not disabled.

A visually disabled button can still be inspected, its handler is still attached. A button that was never rendered doesn't have that problem. It costs almost nothing extra to build it this way from the start.

// how the model gets built

How I actually arrived at these six roles

I didn't start with six roles on a whiteboard. The process matters as much as the result.

1

List every job function

Front desk, billing staff, clinic owners, treating physicians, referring physicians, attorneys, paralegals, the platform operator, every distinct function that touches the system.

2

Group by data access, not job title

Front desk and billing staff ended up sharing a permission set close to Clinic Admin. Paralegals shared the Attorney access pattern rather than getting a separate role.

3

Design roles around access patterns

Two people with different titles who need identical data access can share a role. Two people with the same title but different access needs probably need separate roles.

// the rule that actually matters

If your access control lives only in the frontend, you don't have access control

In Medico, an attorney calling the patient list endpoint gets back only their own clients, because the API pre-filters the query by the attorney's ID pulled from their JWT token. It doesn't matter whether the request came from the app's UI or a hand-crafted API call. The filtering happens at the data layer, not the presentation layer.

Dynamic permission management

Roles shouldn't require a code deploy every time a clinic wants to adjust who can do what. Medico's permission map is data, editable through an admin interface, no engineering ticket, no waiting for a release cycle.

Testing an RBAC system properly

Automated tests assert, for every role, exactly which endpoints return data and which return a filtered response. Manual QA catches the subtle visual leaks automated tests are easy to miss, a tooltip or dropdown showing something it shouldn't.

Frequently asked questions

Good healthcare RBAC matches software permissions to how the organization actually works. Get the modeling right early, retrofitting granular RBAC later is a much harder rebuild.

Talk Through Your Role Model