Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Control matrix

FerroEHR is software. It is not a controller, not a processor and not a certified organisation, so this page makes no compliance claim on anyone’s behalf. It lists the technical controls the product ships or plans, and the article or clause each one is designed to support. Whether a deployment satisfies a legal obligation depends on how the deploying organisation runs it.

Every row comes from the tracker. A control is declared on the issue that delivers it, as a line in the issue body:

Control: <legal source> <article or clause>

The short name resolves to an official publisher URL from a registry inside the generator, so a legal citation on this page is never free text. An issue may declare several controls, one per line. The Control column carries the issue title, unless the body also states the control on its own line, which the generator prefers so that an issue titled as the defect it fixed does not read its defect as the control:

Control-text: <the control, stated as what the product does>

How this page is built

scripts/render/control-matrix.sh queries the tracker with the GitHub CLI, joins each declared control to its legal source and to its current state, and writes this file. A CI job re-runs the generator with --check and fails the build when the committed page no longer matches the tracker, which is what keeps a shipped control from sitting here as “planned”.

  • Shipped: the issue is closed as completed. The merged pull request that closed it is linked in the last column. The one pull request that closes a control regenerates this page as it will read after the merge, so the page never lags a shipped control.
  • Planned: the issue is open. Whether work has started is the issue’s column on the public roadmap board, which this page does not copy: a status that lives in two places disagrees the day one of them moves.
  • Not planned: the issue was closed without the control being built. The row stays visible so the record does not quietly lose it.

The page carries no generation timestamp and no build commit. Both change on every run or every push while the tracker has not moved, which would make the CI staleness check fail on days when nothing was wrong. When this page was last regenerated, and from which commit, is the file’s own git history.

Controls

Legal sourceApplies toArticle or clauseControlIssueStatusClosing PR
GDPREUArt. 15(1)A natural person cannot obtain their own access log: the only retrieval is admin-gated over the whole repository#3240Shipped#3263
GDPREUArt. 17(1)Physical deletion of a party removes its externalised multimedia blobs#3180Shipped#3201
GDPREUArt. 18A restriction register at whole-EHR and single-object grain, with the marked object refused on every read, query, export, event and write path while its stored rows stay untouched#3324Shipped#3410
GDPREUArt. 21(6)A per-EHR research objection that removes the record from population queries, exports and the event stream while leaving reads for care untouched, with the controller’s public-interest override recorded beside it#3325Shipped#3410
GDPREUArt. 25(1)Contributor rules for personal data handling and a PR guard for privacy-boundary changes#3167Shipped#3172
GDPREUArt. 25(2)Refuse identifying data on the clinical side and constrain the subject reference to a pseudonym namespace#3154Shipped#3187
GDPREUArt. 25(2)The compliance layer assumes the Netherlands; it must be jurisdiction-pluggable#3185Shipped#3187
GDPREUArt. 25(2)The identifier scanner does not run on verbatim-replay writes (EHR-Extract import, admin load), and the book says every clinical write is scanned#3237Shipped#3251
GDPREUArt. 25(2)No database constraint holds the subject-reference shape: the CHECK #3154 promised was never built#3241Shipped#3265
GDPREUArt. 30(1)(f)A retention register of the period per content category and jurisdiction with its legal citation, per-EHR anchors, whole-record and per-object holds, a view of what has run out, and a boot-checked ceiling on access-log retention#3346Shipped#3410
GDPREUArt. 32(1)Deploy artifacts provision the demographic role split#3179Shipped#3193
GDPREUArt. 32(1)Row-level security on demographic.national_identifier#3219Shipped#3223
GDPREUArt. 32(1)Schema preparation runs on its own credential, never the clinical runtime role#3224Shipped#3229
GDPREUArt. 32(1)A declared deployment profile: production refuses the postures it cannot prove, research says so in red#3226Shipped#3265
GDPREUArt. 32(1)(a)Split demographic parties into a demographic schema with a non-overlapping runtime role#3153Shipped#3182
GDPREUArt. 32(1)(a)National identifiers in the demographic schema: encrypted storage, keyed lookup, audited resolution#3155Shipped#3189
GDPREUArt. 32(1)(c)Separate encryption keys and per-schema backup handling for the clinical and demographic domains#3157Shipped#3198
GDPREUArt. 32(1)(c)The linkage schema is backed up and its boundary is probed#3220Shipped—
GDPREUArt. 32(1)(d)The storage-parity sweep and node rebuild cover the demographic domain#3178Shipped#3184
GDPREUArt. 32(1)(d)The two-DSN credential separation is exercised by test#3222Shipped#3231
GDPREUArt. 4(5)Split demographic parties into a demographic schema with a non-overlapping runtime role#3153Shipped#3182
GDPREUArt. 4(5)Refuse identifying data on the clinical side and constrain the subject reference to a pseudonym namespace#3154Shipped#3187
GDPREUArt. 4(5)Separate encryption keys and per-schema backup handling for the clinical and demographic domains#3157Shipped#3198
GDPREUArt. 4(5)Linkage service: the party to EHR resolve map as its own schema and role#3158Shipped—
GDPREUArt. 4(5)The subject pseudonym is opt-in: nothing mints it, and an empty subject_namespaces is silent#3232Shipped#3266
GDPREUArt. 5(1)(b)Cross-domain cohort queries with a demographic predicate and a clinical selection#3159Shipped#3275
GDPREUArt. 5(1)(e)Audit retention has no jurisdictional floor: retention_days=1 erases the access log daily while the chain still verifies#3242Shipped#3266
GDPREUArt. 5(1)(e)A retention register of the period per content category and jurisdiction with its legal citation, per-EHR anchors, whole-record and per-object holds, a view of what has run out, and a boot-checked ceiling on access-log retention#3346Shipped#3410
GDPREUArt. 89(1)feat(ext): secondary use leaves through FerroBRIDGE to OMOP in batches over AQL: the CDR keeps the restriction, objection and retention marks, serves AQL over VERSION by time_committed as the batch surface and logs each population query; no in-CDR research domain#3379Planned—
EHDSEUAnnex II 3.2European logging software component: map EHDS logging requirements onto the access event model and ATNA trail#3170Shipped#3205
EHDSEUAnnex II 3.2Auditing off is one info-level line, and fail_mode=open is the silent default: make both visible where an operator looks#3238Shipped#3260
EHDSEUAnnex II 3.2The split clinical role holds no grant on the audit schema, so a separated deployment cannot write its own access log#3267Shipped#3270
EHDSEUAnnex II 3.2(a)The access log records no accessing organisation (EHDS Annex II 3.2(a))#3204Shipped#3213
EHDSEUArt. 9A natural person cannot obtain their own access log: the only retrieval is admin-gated over the whole repository#3240Shipped#3263
EHDSEUChapter IVfeat(ext): secondary use leaves through FerroBRIDGE to OMOP in batches over AQL: the CDR keeps the restriction, objection and retention marks, serves AQL over VERSION by time_committed as the batch surface and logs each population query; no in-CDR research domain#3379Planned—
EDPB 01/2025EUpseudonymisation domainSplit demographic parties into a demographic schema with a non-overlapping runtime role#3153Shipped#3182
EDPB 01/2025EUpseudonymisation domainLinkage service: the party to EHR resolve map as its own schema and role#3158Shipped—
EDPB 01/2025EUpseudonymisation domainCross-domain cohort queries with a demographic predicate and a clinical selection#3159Shipped#3275
UAVGNLArt. 46Refuse identifying data on the clinical side and constrain the subject reference to a pseudonym namespace#3154Shipped#3187
UAVGNLArt. 46National identifiers in the demographic schema: encrypted storage, keyed lookup, audited resolution#3155Shipped#3189
WabvpzNLArt. 15eA natural person cannot obtain their own access log: the only retrieval is admin-gated over the whole repository#3240Shipped#3263
NEN 7513NLactor roleThe access record carries no actor role or authorisation basis, which NEN 7513 requires and the RBAC layer already holds#3239Shipped#3262
NEN 7513NLevent contentPer-domain access logging for reads and queries aligned with NEN 7513 and EHDS Art. 9#3156Shipped#3188
NEN 7513NLevent contentDomain-level access events discard their EmitOutcome, so fail_mode=closed does not cover them#3235Shipped#3246
NEN 7513NLretentionAudit retention has no jurisdictional floor: retention_days=1 erases the access log daily while the chain still verifies#3242Shipped#3266
BDSGDE§ 35 Abs. 2 and 3A restriction register at whole-EHR and single-object grain, with the marked object refused on every read, query, export, event and write path while its stored rows stay untouched#3324Shipped#3410
SGB VDE§ 309 Abs. 3A retention register of the period per content category and jurisdiction with its legal citation, per-EHR anchors, whole-record and per-object holds, a view of what has run out, and a boot-checked ceiling on access-log retention#3346Shipped#3410
GDNGDE§ 6 Abs. 1A retention register of the period per content category and jurisdiction with its legal citation, per-EHR anchors, whole-record and per-object holds, a view of what has run out, and a boot-checked ceiling on access-log retention#3346Shipped#3410
DSGCHArt. 25 Abs. 2 lit. dA retention register of the period per content category and jurisdiction with its legal citation, per-EHR anchors, whole-record and per-object holds, a view of what has run out, and a boot-checked ceiling on access-log retention#3346Shipped#3410
EPDVCHArt. 10A retention register of the period per content category and jurisdiction with its legal citation, per-EHR anchors, whole-record and per-object holds, a view of what has run out, and a boot-checked ceiling on access-log retention#3346Shipped#3410

The short names above resolve to these publishers. The linked text is the authority; nothing on this page restates it.

EU and INT apply to every deployment. A two-letter country code is national law or a national standard, and applies to a deployment in that country: FerroEHR is an openEHR CDR, openEHR is not a Dutch standard, and a deployment elsewhere answers to its own equivalents rather than to these. Adding a jurisdiction is a registry entry plus the controls that cite it.