Building compliant software in healthcare / The rules that apply to your code
Minimum necessary in a permission model
Minimum necessary is the HIPAA principle everyone can state and almost nobody enforces in software. It is not a policy problem. It is a permission-model problem, and permission models only ever grow wider unless something is actively checking.
Published August 22, 2026. Editorial.
Key takeaways
- Minimum necessary means users reach only the PHI their function requires, which is a statement about the running system rather than about a policy.
- Healthcare permission models face a real tension: restricting access too tightly causes clinical harm, so the answer is scoped access plus a well-logged emergency path.
- Role definitions stay correct while assignments grow wider over time, so reviewing roles finds nothing. Effective access per person is the thing to compute.
- The enforceable version is a negative assertion: what each role must not reach, tested on every change.
Minimum necessary is easy to say and genuinely hard to build, and the difficulty is not technical. It is that healthcare has a real, unavoidable tension between restricting access and delivering care, and most teams resolve that tension by giving everyone broad access without saying so and relying on policy to constrain behaviour.
That resolution is understandable and it is not compliant, because a policy is not a technical control and the Security Rule's access control standard is about allowing access only to those who have been granted rights [1].
The tension is real, so start by naming it
In a clinical setting, a permission model that is too tight causes harm. The nurse who cannot see the record of the patient in front of them, the covering physician locked out of a chart at two in the morning, the specialist who needs history from another department: each of those is a patient safety problem, and every clinician has a story about a system that blocked their work.
The Security Rule acknowledges this directly by making emergency access procedure Required [1]. The intended design is not "restrict everything." It is scoped access for ordinary work, plus a deliberate, logged path for the cases the scope did not anticipate.
That design is the whole answer, and teams skip it because building the second half is more work than granting broad access. Once the emergency path exists and is properly logged, narrowing ordinary access stops being dangerous, because the failure mode of too-tight scoping is now an inconvenience with a defined remedy rather than a clinical risk.
Why role review finds nothing
The standard approach to minimum necessary is an annual access review that examines role definitions and confirms they look reasonable. They do look reasonable. The definitions were written thoughtfully and nobody has changed them.
The change happens in assignments, and it only goes one way: access grows. Someone joins as a scheduler and gets the scheduling role. They move to billing and get the billing role. Nobody removes scheduling, because removing access has no deadline, no requester, and a real chance of blocking someone's work. Multiply by a few years and a few dozen staff and the effective access in the organisation bears little relationship to the correct model in the code.
The review that finds this computes effective permissions per person and compares them to that person's current function. It produces an uncomfortable list of named individuals with more access than their job requires, which is exactly why it is the version that works and the version that gets avoided.
The harder variant is that effective access is frequently the union of grants across several systems: the clinical application, a reporting tool with its own permissions, a database group, a cloud IAM policy, and a shared credential in a password manager. Each looks defensible alone. Nobody computes the union, and the union is what a person can actually reach.
Write down what each role must not reach
The lasting engineering answer is to write down what each role must not reach, as assertions, and run them on every change.
Positive tests do not protect you here. A test asserting that the billing role can read billing records keeps passing forever and says nothing about the fourteen endpoints added since. The billing role can now reach clinical notes through a new shared component, and every existing test still passes.
The negative assertion is the one that fails when access grows beyond its scope. It is also readable by a compliance reviewer in a way a permission matrix is not: "the scheduling role must not be able to read clinical notes" is a sentence somebody can agree or disagree with, whereas a grid of two hundred permission cells is something everybody approves and nobody checks.
Write these per role, covering the categories of PHI the role should never reach, and make them part of the check suite rather than a document. This is work across many combinations, roles multiplied by data categories multiplied by interfaces, which is precisely the kind of thoroughness that was never affordable before and now takes an afternoon.
Test at the endpoint, not the screen
The most common technical defect behind a minimum necessary failure is authorisation implemented as a rendering decision.
The chart link is not shown to users without the clinical role. The menu item does not appear. And the endpoint behind it answers anyone authenticated who calls it, because the check was in the component that decided what to display. This is not an exotic bug; it is the default outcome when the screen and its authorisation are built in the same afternoon by the same person.
Any test that drives the user interface will pass. The test has to call the endpoint directly, with each role, asserting both the permitted and the forbidden outcomes.
Scoping by relationship, not just by role
The more sophisticated version of minimum necessary in clinical systems is that access should depend on the relationship to the patient, not only on the job title. A nurse should reach the records of patients on their unit rather than every patient in the hospital.
This is harder to build, because it requires the system to know about care relationships, assignments, and coverage, and those change constantly. It is also where the largest reduction in unnecessary access is found, since role-based scoping alone typically leaves every clinician able to reach every patient.
Two practical notes. Relationship-based scoping needs the emergency path more than any other model, because the relationship data will be wrong or missing at exactly the wrong moment. And it makes the audit trail far more useful, because recording the relationship that justified access, as described on audit controls under the Security Rule, turns review from guesswork into a question with an answer.
Service accounts and integrations
The broadest access in most healthcare systems belongs to something that is not a person: the integration credential for a health information exchange, the reporting job that reads everything to build a dashboard, the analytics pipeline, the backup process.
These are provisioned once, generously, because narrowing them would have required knowing exactly what each needed and nobody had time. Then they run for years. Minimum necessary applies to them, and unlike the human version, narrowing them produces no awkward conversations. Compute what each actually touched over a representative period and reduce the grant to match.
If your permission model has been running for a few years and nobody has computed effective access recently, that is where to start. Get in touch and we will run it with you.
Best for
- Clinical products where staff can currently reach far more patients than their work requires
- Organisations that have grown headcount and role complexity faster than they have removed access
Avoid if
- There is no emergency access path yet, since narrowing ordinary access without one creates clinical risk
Check before you decide
- Compute effective permissions per person as the union across every system, then compare to current function
- Call a restricted endpoint directly with a role that should not have it, bypassing the interface
- Ask whether access is scoped by care relationship or only by role
- List integration and service accounts, and compare granted access to what they actually used last quarter
Common questions
What does minimum necessary mean for a software permission model?
That users reach only the PHI their function requires, which is a property of the running system rather than of a policy. Relying on a policy to constrain behaviour while granting broad technical access does not satisfy an access control standard concerned with who has been granted rights.
How do you narrow clinical access without causing patient harm?
By pairing scoped ordinary access with a deliberate, well-logged emergency path, which is the design the Security Rule intends by making emergency access procedure Required. Once that path exists, the failure mode of too-tight scoping becomes an inconvenience with a defined remedy rather than a clinical risk, and narrowing stops being dangerous.
Why does an annual role review fail to find access problems?
Because role definitions stay correct while assignments grow wider over time. People accumulate roles as they change function and rarely lose the previous ones, so the review that works computes effective permissions per named person and compares them to that person's current job, which is precisely the uncomfortable version that gets avoided.
Why write down what a role must not reach?
Because positive tests keep passing as the system grows and say nothing about newly added endpoints. A negative assertion fails when access grows beyond its scope, and it is also readable by a compliance reviewer, since 'the scheduling role must not read clinical notes' is a sentence someone can agree or disagree with in a way a two-hundred-cell permission grid is not.
Should clinical access be scoped by care relationship?
It is where the largest reduction in unnecessary access is found, since role-based scoping alone usually leaves every clinician able to reach every patient. It requires the system to track relationships and coverage that change constantly, so it depends more heavily on a reliable emergency path, and it makes audit review far more answerable because the justifying relationship can be recorded alongside the access.
Does minimum necessary apply to service accounts and integrations?
Yes, and it usually applies less strictly than it should. Integration credentials for a health information exchange, reporting jobs, analytics pipelines, and backup processes are typically provisioned once with broad access because scoping them precisely takes time nobody had, then run unreviewed for years. Computing what each account actually touched over a period and reducing the grant to match is direct work with no awkward conversation attached.
Why should authorisation be tested at the endpoint rather than the screen?
Because the most common defect is authorisation implemented only as a rendering decision: a menu item or chart link is hidden from a role, but the underlying endpoint answers anyone authenticated who calls it directly. A test that only drives the interface will pass every time, so the check has to call the endpoint boundary directly with each role and assert both the permitted and forbidden outcomes.
Is enforcing minimum necessary worth the engineering effort?
It is, because the alternative is broad access that depends on policy alone, which does not satisfy an access control standard concerned with who has technically been granted rights. Writing negative assertions per role against every data category and interface is work across many combinations that was rarely affordable as a manual process, but it is now realistic to build and run on every change rather than review once a year.
Related reading
A practical pre-launch security review for a small team
You do not need perfect security to launch. You need to check the few basics that find most real problems, and to know when the risk is big enough to bring in a specialist.
What good code review looks like when nobody wrote the code
With human code, the author is the first check and review is the second. With generated code, review is the only check. That one change alters most of what a reviewer should be doing.
More in The rules that apply to your code
Audit controls under the Security Rule
One sentence in the Security Rule creates the widest gap between what healthcare teams build and what the rule describes. Audit controls require mechanisms that record and examine activity in systems containing PHI, and in healthcare the activity that matters most is the one almost nobody logs: reading.
Encryption and the proposed Security Rule update
Encryption of PHI is not currently required by the HIPAA Security Rule. It is Addressable, which surprises people and explains a good deal of real-world practice. A proposed update would change that, and the sensible response is to build now in a way that makes the change a configuration matter rather than a project.