Clinical Data Repository Architecture with openEHR: Services, Versioning, and Identity
An openEHR-based Clinical Data Repository (CDR) is best understood not as a database but as a small set of formally specified services over a versioned, model-driven store. The openEHR Platform Service Model defines these service interfaces abstractly — as a standard reference that implementers map onto their own architectures — and the openEHR REST API gives them a concrete, portable HTTP form [1]. Three services carry the core workload: the EHR Service, managing patient EHR containers and their versioned compositions; the Definitions (knowledge) Service, storing and serving operational templates and registered queries; and the Query Service, executing AQL against stored data. Around them sit supporting services defined in the same model — notably a Demographic Service for party identity and an EHR Index for locating records across systems.
Whether these run as a unified platform or as decomposed microservices is a deployment decision, not an architectural one — the service contracts are the architecture. What is non-negotiable is the write path: all inbound clinical data enters as compositions through the canonical openEHR API and is validated against its Operational Template before persistence [5]. Integration layers — HL7 v2 feeds, FHIR facades, application backends — feed this single validated front door rather than writing to storage directly, which is precisely what keeps a CDR's data trustworthy at scale.
Core CDR Services at a Glance
| Service | Responsibility | Key Artifacts | Architectural Notes |
|---|---|---|---|
| EHR Service | EHR containers, versioned compositions, contributions, EHR status | EHR (UUID-keyed), COMPOSITION, CONTRIBUTION | The only write path for clinical data; every commit validated against its OPT |
| Definitions Service | Knowledge management: templates and stored queries | Operational Templates (OPTs), registered AQL queries | Deploys clinical models at runtime — no software release per model change |
| Query Service | AQL execution over stored compositions | Ad-hoc and stored queries, result sets | Read workload concentrates here; indexing strategy determines performance |
| Demographic Service | Party identity, roles, relationships | openEHR demographic model or external MPI/FHIR Patient store | Deliberately separated from clinical data — a designed privacy measure |
The Versioning Model: Nothing Is Ever Overwritten
The single deepest architectural difference between an openEHR CDR and a conventional relational EHR is change control. Every composition lives inside a versioned object (a version-controlled record): each commit creates a new immutable version linked to its predecessor, grouped into a CONTRIBUTION — the change-set object recording what was committed together, by whom, when, and why [3]. Commit audits are mandatory in the model, and digital signatures and hashes are available at the versioned-object level for deployments that need tamper-evidence with cryptographic strength. The REST API preserves these semantics even behind friendly verbs: PUT, POST, and DELETE on change-controlled resources must be executed internally as contribution-wrapped version commits — meaning a "delete" is itself a new version with a deleted lifecycle state, not a removal [5].
The architectural consequences are concrete:
- Point-in-time reconstruction: because the full version history and its audit trail are first-class data, any patient record can be reconstructed as it stood at any moment — a property medico-legal and clinical-safety requirements increasingly demand, and one that is structurally guaranteed rather than reimplemented per application [4].
- Storage and backup planning: data is never overwritten, only superseded, so capacity models must account for version accumulation, and backup/restore strategies must preserve version and contribution integrity — restoring "just the latest state" is not a faithful restore of an openEHR record.
- Amendment and correction workflows: clinical amendments map naturally onto new versions with appropriate audit change types, so application teams get correction semantics from the platform instead of inventing soft-delete columns and shadow tables — in our experience one of the most underrated simplifications openEHR brings to application design.
Identity Architecture: EHR IDs, Subjects, and the MPI
The openEHR EHR is a root object identified by a globally unique EHR ID, with its EHR_STATUS optionally carrying the identifier of the subject of care [2]. Crucially, the architecture deliberately separates the clinical record from identifying demographics — an explicit openEHR security measure: the EHR holds clinical content keyed by an opaque UUID, while who the patient is lives in a demographics service, with the subject reference in EHR_STATUS pointing into that external identity namespace (the party-reference pattern of the openEHR Reference Model, using external references with an explicit namespace).
This separation is a privacy asset and an integration obligation. In multi-system deployments, the EHR ID must be consistently linked to a master patient index subject identity — and in our experience, failure to establish and govern that linkage is the root cause of fragmented patient records across sources: the same person accumulating multiple EHRs, or worse, two people sharing one. In national and regional deployments the authoritative subject store is typically a dedicated demographics service or a FHIR Patient resource server fronted by MPI matching, with the CDR holding only the cross-reference. Architecturally, treat three things as one design problem: the subject namespace strategy (which identifier domains exist and who owns them), the matching authority (where merge/link decisions are made — never in the CDR), and the EHR-ID-to-subject linkage lifecycle (what happens in the CDR when the MPI merges or splits identities). Deciding these on day one is cheap; retrofitting them across millions of versioned compositions is not.
Putting It Together
The reference shape for a mid-to-large deployment, then: integration layers normalize inbound data and commit template-valid compositions through the EHR Service; the Definitions Service governs which clinical models and queries are live, deployable at runtime; the Query Service serves applications and analytics through AQL, preferably via stored queries; and identity resolves through a demographics/MPI layer that the CDR references but never adjudicates. Every box in that picture is specified by an open standard, which is the strategic point — the architecture, not any vendor's product, is what your data depends on.
Where CaboLabs Fits
This architecture is not theoretical for us — it is what CaboLabs builds. Our openEHR-native clinical data repository, Atomik, implements the pattern end to end: EHR and composition management with full contribution-based versioning, runtime template deployment with OPT validation on every commit, AQL querying, and demographic services with MPI-grade patient matching designed for multi-system and distributed deployments. Behind it sits a track record that includes EHRServer, our earlier open-source openEHR CDR, and years of consulting on CDR architecture, identity strategy, and standards-based integration across openEHR, FHIR, and HL7.
If you are designing a clinical data platform, evaluating openEHR CDRs, or untangling patient identity across systems, talk to us at cabolabs.com — we've built the repository this article describes, and we can help you build yours.
