Skip to content

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:

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.

  1. Establish the request: patient, requester, recipient, purpose, operation, the data in scope, and the effective moment.
  2. 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.
  3. 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".
  4. Apply the decision to everything in the response — the requested resources, included resources, narrative, attachments and derived content — before serialization.
  5. 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.