11. Security
Requirement prefix: X11.
openEHR fixes the audit model and deliberately leaves access control open. This section says what the crate supplies on top, and — at least as importantly — what it does not.
The trust boundary#
- X11.1 The crate MUST NOT authenticate, and MUST document that the deployment supplies authentication, group membership, transport security, key storage, consent capture, and log retention.
- X11.2 The crate MUST record who acted on every version (
V8.13). Authentication is outside on purpose; attribution is not — a perimeter knows the identity and only the record knows which nodes were touched, so neither can answer an access complaint alone.
Access control#
- X11.3
EHR_ACCESSsettings in a scheme the crate does not implement MUST be carried unchanged through a read-modify-write, and MUST NOT be evaluated. - X11.3a Dispatch between schemes MUST be by the declared scheme name and never by object shape. A shape-based reader would match a foreign policy as the reference scheme and discard its attributes, turning an intact un-evaluatable policy into an empty one that denies and looks deliberate.
- X11.4 Every access decision MUST default to deny. There MUST be no "unknown" outcome a caller might read as permissive.
- X11.5 Denial reasons MUST be distinguishable — no policy recorded, scheme not implemented, principal not in a permitted group — because each calls for a different response, and "denied" leaves an operator nothing to act on.
- X11.5a Reading the audit trail MUST be expressible as an operation separate from reading clinical content. An information-governance officer investigating an access complaint needs the trail and not the record.
PHI in output#
- X11.6 No
Displayimplementation may render PHI.DV_IDENTIFIERrenders its type and issuer;DV_MULTIMEDIAhas noDisplayand aDebugthat prints shape only. - X11.7 No error may echo a submitted value. An error message is the one place a value reaches a log, a response, and a support ticket at once.
- X11.7a The single exception is a lexical rejection of design-time vocabulary — an archetype id, a terminology id, a code — where an error that will not name the identifier is unactionable. Even there the echoed text MUST be truncated, so that a document passed to a parser by mistake is not logged.
- X11.8 A wrapper MUST be provided for values that must pass through code
that logs, hiding them from
DisplayandDebugwhile keeping them for serialization. Protecting serialization would corrupt the record rather than protect it; the accidents happen in logs.
The audit chain#
- X11.9 The chain MUST digest each entry over its predecessor, so that altering any entry invalidates every entry after it.
- X11.10 Documentation MUST state plainly what an unkeyed chain buys: it detects careless or unaware modification and supports an external witness, and it does not stop an informed attacker with write access, because the digests are unkeyed over a published pre-image.
- X11.11 A keyed tag (
HMAC-SHA-256) MUST be available, and the key MUST live in the process rather than in the store it protects. - X11.12 Tag comparison MUST be constant-time. A timing oracle lets an attacker with write access recover a valid tag byte by byte.
- X11.13 Only a tag mismatch is a tampering finding. A missing tag, a tag naming a key this process does not hold, and a malformed tag MUST each be reported as what they are. Reporting a key-distribution problem as forgery burns an incident response.
- X11.14 Key identifiers MUST travel with tags, so rotation is additive. Without the identifier, rotating would invalidate all history at once — indistinguishable from mass tampering.
- X11.15 Chains MUST NOT be backfilled. A chain assembled after the fact attests only that the rows look consistent now, which is exactly what an attacker who rewrote them would produce. Beginning late MUST be recordable and recorded.
- X11.16 Chain keys MUST be at least 32 bytes and MUST be zeroized on drop.
- X11.17 A
Debugon a key MUST NOT print its material. - X11.18 SHA-256, not SHA-1 (
D3.27). - X11.19 A checkpoint form MUST be available that carries no patient data — counts and digests only — so it can be shipped to a long-retention log where clinical data must not go. That separation is what makes a log-based witness practical.
Redaction#
- X11.20 Withheld content MUST be masked, not deleted:
272|masked|(R4.7). Deleting turns "the patient has withheld their sexual health history" into "the patient has no sexual health history", which is a clinical statement nobody made. - X11.21 A redacted document MUST still satisfy validation. A filter that produced something the receiving system rejects has achieved nothing.
- X11.22 Redaction MUST report how much it withheld and MUST NOT name what. An access log saying "12 elements withheld" is auditable; one saying "HIV status withheld" is a disclosure inside the audit trail.
- X11.23 A recorded redaction reason is written into the document and MUST therefore not name the withheld value or its clinical category.
- X11.24 Redaction MUST fail closed: on error nothing is returned, so a caller cannot forward the unredacted original by mistake.
- X11.25 Redaction rules address
ELEMENTs. Composer, participations, and the audit trail are not withheld by an element rule, and the documentation MUST say so — stripping those is de-identification, a different operation with different rules.