Skip to content

The HIPAA boundary is group math

The most instructive thing in the lab is also the smallest: the line between staff who can open patient records and staff who cannot is a single group-nesting edge. No per-user access-control entry, no per-share user list. Just group membership and one rule about how Samba reads it.

There are two meta-groups. Neither contains a person directly:

  • Clinicians contains the 15 clinical and ancillary groups (Cardiology, Pediatrics, Radiology, and so on). Its members are groups.
  • GH-Staff contains Clinicians plus the four admin groups (Administration, Billing, Medical-Records, IT).

The patient-data share is gated simply:

[phi]
valid users = @AD\Clinicians
read only = No

Notice what is not there: no usernames. john.carter is never mentioned.

john.carter is a member of Cardiology. Cardiology is a member of Clinicians. When he connects to [phi], Samba does not just check his direct group list; it expands the transitive set of groups in his Kerberos token (AD’s tokenGroups), which includes every group he belongs to through nesting. So Clinicians is in his effective token, and valid users = @AD\Clinicians matches. He is in.

That transitive expansion is something flat Unix groups cannot do, and it is the entire mechanism here.

madonna is a member of Billing. Billing is a member of GH-Staff, but not of Clinicians. So her transitive token contains GH-Staff (she can read the all-staff share) but never Clinicians. When she connects to [phi], nothing in her token matches valid users = @AD\Clinicians, and Samba denies her at the tree connect with NT_STATUS_ACCESS_DENIED.

flowchart LR
  carter["john.carter"] --> Cardiology
  Cardiology --> Clinicians
  madonna["madonna"] --> Billing
  Billing --> GH["GH-Staff"]
  Clinicians --> phi(["[phi] share"])
  GH -. "no path to Clinicians" .-> phi
  phi --> allow{{"carter: ALLOWED"}}
  phi --> deny{{"madonna: DENIED"}}
  Clinicians -.->|grants| allow
  GH -.->|blocked| deny

You could instead list every clinician on the phi share. That list would be wrong the moment someone is hired, transferred, or leaves, and it would have to be maintained on every patient-data share separately. The nesting approach moves the decision to one place: a clinic group is either under Clinicians or it is not. Add a new clinic and put its group under Clinicians, and every member instantly has the correct PHI access, with no share edited.

The policy lives in the shape of the group tree, not scattered across ACLs. That is what makes it auditable: to answer “who can see patient data?” you read one membership list, not every share definition.

Terminal window
make test-clinic-access

Watch john.carter reach phi and madonna get denied, with neither named anywhere near the share. Change the boundary by re-parenting a group, never by touching a share. The full matrix is in groups and shares.