Privacy Directives (Lockbox)¶
Introduction¶
A privacy directive is an instruction from an individual restricting what a health information custodian may do with their personal health information. PHIPA gives an individual the right to withhold or withdraw consent to the collection, use or disclosure of their information; Ontario practice calls the result a lockbox.
It is modelled as a Privacy Directive
— a Consent resource whose base rule is a denial.
Nothing in this estate yet consults a directive before disclosing. Storing one restricts nothing today; see What is not implemented at the foot of this page.
The reading rule¶
An active directive means the restriction is in force.
An active item consent means the patient agreed.
Both are Consent, both carry scope = patient-privacy, and one query returns them together.
GET Consent?patient={id}&category=https://fhir.apps.health/CodeSystem/nexus-consent-family|privacy-directive&status=active
But status is not where the decision is, in any family. Every Consent profile in this guide
states its decision in provision.type on the root provision — deny restricts, permit grants —
and status says only whether the record is operative. Read provision.type and a directive, a
declined item consent and a refused app consent all come back restricted without your code knowing
which is which. The full rule is on the overview.
Absence of a directive is not permission¶
A search returning no active directive means no restriction has been recorded. It does not mean disclosure is authorized.
Whether a disclosure is lawful without a directive is a question for the applicable policy and the purpose of the disclosure. This resource is one input to that decision, and its absence is the absence of one input — not an answer.
This is stated first because it is the mistake that is invisible. Reading a lockbox as permission is loud and this guide warns about it four times; treating an empty result set as consent looks exactly like a careful implementation, passes every test written against patients who have no directives, and is reached by writing no code at all.
What a directive can say¶
| Dimension | Element | If absent |
|---|---|---|
| Which act | provision.action — collect, access, use, disclose |
All acts restricted |
| Against whom | provision.actor |
Everyone |
| Which records | provision.data |
The whole record, including future information |
| For how long | provision.period |
In force while status = active, with no end |
The first three read fail-closed: an unnamed dimension is the broadest restriction, not the narrowest, because a privacy control that fails open is not a control.
provision.securityLabel is not one of them, and the difference is worth understanding rather
than memorising. The first three narrow a restriction that already exists — a directive restricts
every act, against everyone, over the whole record, until it says otherwise. A security label is an
additional selector, restricting records that carry a given classification. Absent, it selects
nothing extra; the restriction is whatever the other three dimensions already made it. Reading its
absence as "restrict everything by label" would not be fail-closed, it would be meaningless.
Worked shapes¶
A whole-record disclosure restriction. No data, so it covers information recorded after the
directive was given:
status = active
category = privacy-directive
provision.type = deny
provision.action = disclose
A single-document restriction. Covers that document and nothing else — including not covering a later document about the same episode:
provision.type = deny
provision.action = disclose
provision.data = { meaning: instance, reference: DocumentReference/... }
A restriction with a standing break-glass exception:
provision.type = deny
provision.action = disclose
provision.provision.type = permit
provision.provision.actor = the users who may break the glass
provision.provision.purpose = BTG
What comes back, and how to tell it apart¶
Worked examples, with narrative explaining each decision in place:
- Whole-record lockbox with a standing break-glass exception
- Single-document lockbox, no exception
- The audit entry written when somebody breaks the glass
A search without the category filter returns families mixed. This is what that looks like, reduced to the elements that decide the reading:
{ "resourceType": "Bundle", "type": "searchset", "entry": [
{ "resource": {
"resourceType": "Consent",
"status": "active",
"scope": { "coding": [{ "code": "patient-privacy" }] },
"category": [{ "coding": [{
"system": "https://fhir.apps.health/CodeSystem/nexus-consent-item",
"code": "email" }] }]
}},
{ "resource": {
"resourceType": "Consent",
"status": "active",
"scope": { "coding": [{ "code": "patient-privacy" }] },
"category": [{ "coding": [{
"system": "https://fhir.apps.health/CodeSystem/nexus-consent-family",
"code": "privacy-directive" }] }],
"provision": { "type": "deny" }
}}
]}
Both are active. Both are patient-privacy. The first means the patient agreed to be emailed. The
second means a restriction is in force. The only element that separates them is category, and the
only element carrying the second one's decision is provision.type.
A consumer reading status across that Bundle gets "active, active" and learns nothing.
Suppressing is only half of it¶
Where a directive causes information to be withheld from a disclosure, PHIPA obliges the custodian to tell the recipient that what they received is incomplete. A receiving clinician who cannot see the gap reads the record as whole and treats the patient on that basis.
That notice is a security label on the released Bundle or packet, and it is covered on Security labels. A release path that honours a directive without emitting it has implemented the dangerous half.
The evaluation contract¶
This is what a release path must do. None of it is implemented today.
- Establish the request: patient, requester, recipient, purpose, operation, the data in scope, and the effective moment.
- Find every applicable directive for that patient, plus the organizational and legal policy that applies. Define which rule families combine and which takes precedence — and publish that rule, so the outcome does not depend on database iteration order.
- Deny when an applicable restriction is not satisfied. Permit an exception only through an explicitly recognised authorization, or another documented legal basis. Never through "latest Consent wins".
- Apply the decision to everything in the response — the requested resources, included resources, narrative, attachments and derived content — before serialization.
- Record what the decision relied on: the policy version and the directive versions consulted, so the decision can be reconstructed later.
Where consent state cannot be determined, use a documented failure policy appropriate to the operation. Do not silently grant.
Lifecycle¶
A directive is superseded, not edited. When the individual changes their instruction, the prior
directive moves to inactive and a new one records the new instruction.
The reason is evidentiary. A directive is what an auditor holds up to justify or condemn a release decision, and "what did this say on the day we released the record" has to be answerable without reconstructing it from version history.
This differs from item consent, which keeps one resource per item and updates it in place. Both are deliberate and each suits its own lifecycle.
Withdrawal must take effect for subsequent decisions, must invalidate relevant cached
authorizations, and must preserve the prior record. Setting a permitting Consent inactive does not
by itself express an ongoing prohibition — where the individual's instruction is a restriction, it
needs an active directive that says so.
Two traps¶
Security labels are a high-water mark, not an equality test. A rule written against restricted
also catches every lower classification, which in a chart where most resources carry no elevated
label is close to restricting everything. The failure over-restricts rather than over-discloses, so
it denies a clinician information rather than leaking any — but it denies it silently. Prefer
explicit provision.data selectors. The rule, R4's own wording for it, and how it interacts with the
confidentiality axis are on Security labels.
Data selectors are a list of what exists now. "Nothing from this clinic, ever" cannot be expressed as a list of today's resource ids, and this release defines no criteria-based selector. Express it by naming no data at all.
Divergences worth knowing¶
Root provision.type is required, following IHE PCF and Ontario's PCOI, and against R4's own
element text ("Not permitted in root rule"). A directive carrying no root type is malformed; fail
closed rather than inferring permit. Every Consent profile in this guide takes the same side of
that divergence, so there is one convention to learn rather than one per family.
provision.action is used, and PCF prohibits it. PCF targets document sharing, where disclosure
is the only act in play. Restricting internal use of a record by staff who already hold it is a
different instruction, and Ontario requires it to be expressible.
policyRule is not used. Its bound code system contains no Canadian concept; the nearest-looking
code is the US Common Rule for human-subjects research. policy.uri names the actual instrument.
What is not implemented¶
No read, search, _include, history, packet-assembly, attachment-download, summary-generation,
export or SMART-authorization path in this estate consults a directive. Nothing invalidates a cached
authorization when one changes. An attachment URL issued before a restriction was recorded still
resolves.
Storing a directive restricts nothing today. The model defines what a restriction is; a release path has to honour it.