Back to Docs

Architecture

Last updated

Interactive diagrams of the Health Dataspace v2 architecture — 5-layer graph model, data flows, deployment topology, service dependencies, and identity trust framework.

1. Five-Layer Knowledge Graph

The Neo4j knowledge graph organises health data across five architectural layers: DSP Marketplace (connector discovery), HealthDCAT-AP (dataset metadata), FHIR R4 (clinical data), OMOP CDM (research analytics), and Ontology (terminology alignment).

Fig 1. Five-layer knowledge graph, with the labels and relationships the seeds create. The FHIR nodes carry the same CODED_BY links as their OMOP counterparts; ICD-10 codes exist on Condition only.

2. Data Flow Pipeline

Synthetic patient data flows from Synthea generation through FHIR R4 resource loading into Neo4j, then transforms to OMOP CDM for research analytics. Each stage preserves full provenance through graph relationships.

Fig 2. End-to-end data flow from Synthea to analytics

3. Deployment Topology

The full JAD stack runs 25 Docker Compose services (profiles included) across six layers: infrastructure (Traefik, PostgreSQL, Vault, NATS, Keycloak), EDC-V / DCore (Control Plane, dual Data Planes), Identity (Identity Hub, Issuer Service), CFM (Tenant/Provision Managers, 4 background agents), Application (Neo4j, Proxy, UI), and a static GitHub Pages export. The same topology is deployed to Azure Container Apps at ehds.mabu.red (21 Container Apps and 9 Container Apps jobs on 2026-10-04, see ADR-012). Arrows show runtime dependencies.

Fig 3. Full deployment topology — 25 services with their dependencies

Operating hours on Azure

The Azure deployment runs Monday to Friday, 05:00 to 18:00 UTC, and is stopped outside those hours (ADR-053). Stopping is a real stop through the Container Apps API, not scale-to-zero, because nearly every service is called by another one and would never reach zero replicas. The UI is the exception: it sleeps at zero replicas, wakes for a visitor and serves an offline notice that links the static export.

StepEvening stop (18:00 UTC)Morning start (05:00 UTC, Mon to Fri)
1UI to offline mode, min 0PostgreSQL Flexible Server, wait until Ready
220 Container Apps stopped, consumers firstVault, Keycloak, Neo4j, NATS, proxy, enricher
3PostgreSQL Flexible Server stoppedEDC control plane, data planes, identity, CFM
4UI back online, then the Keycloak login check

Berlin public holidays skip the start. The catalog crawler runs in office hours only. A night or weekend session holds the stack with the repository variable LIVE_DEMO_HOLD_UNTIL; see the off-hours runbook.

4. Service Dependencies

Complete inventory of all services in the docker-compose.yml and docker-compose.jad.yml stacks, their exposed ports, upstream dependencies, and purpose.

ServiceLayerPort(s)Depends OnPurpose
TraefikInfrastructure:80 / :8090--API gateway, reverse proxy, *.localhost routing
PostgreSQL 17Infrastructure:5432--Shared database (9 DBs: cfm, controlplane, dataplane, dataplane_omop, identityhub, issuerservice, keycloak, redlinedb, taskdb)
HashiCorp VaultInfrastructure:8200--Secrets store with file storage, so a restart keeps every key (since 2026-09-26; on Azure it stores in the Flexible Server, ADR-046)
NATS JetStreamInfrastructure:4222 / :8222--Async event mesh for DSP protocol events
KeycloakInfrastructure:8080 / :9000PostgreSQLOIDC SSO provider, realm edcv, 8 demo users across 5 roles
vault-bootstrapInfrastructure--Vault, KeycloakInit sidecar: seeds Vault secrets and Keycloak config
vault-unsealInfrastructure--VaultSidecar: initialises Vault once, then unseals it after every restart
sigletInfrastructure--VaultToken signing and certificate exchange for the EDC 0.18 data planes (#97)
Control PlaneEDC-V / DCore:11003PostgreSQL, Vault, NATS, KeycloakEDC-V runtime: DSP negotiation, management API, policy engine
Data Plane FHIREDC-V / DCore:11002PostgreSQL, Vault, Control PlaneDCore data plane for FHIR R4 resource transfer
Data Plane OMOPEDC-V / DCore:11012PostgreSQL, Vault, Control PlaneDCore data plane for OMOP CDM data transfer
Identity HubIdentity:11005PostgreSQL, Vault, KeycloakDCP: DID resolution, Verifiable Credential storage
Issuer ServiceIdentity:10013PostgreSQL, Vault, KeycloakVC issuance: EHDS membership, data permits, org credentials
Tenant ManagerCFM:11006PostgreSQL, KeycloakCFM: multi-tenant participant management
Provision ManagerCFM:11007PostgreSQL, Keycloak, Control PlaneCFM: automated resource provisioning
cfm-cp-shimCFM--Control Planenginx shim: the CFM agents call Management API v5alpha, EDC 0.18 serves v5beta (#181)
cfm-keycloak-agentCFM--KeycloakBackground: syncs Keycloak realm configuration
cfm-edcv-agentCFM--Control PlaneBackground: manages EDC-V connector lifecycle
cfm-registration-agentCFM--Identity HubBackground: handles participant DID registration
cfm-onboarding-agentCFM--Tenant ManagerBackground: automates tenant onboarding workflows
Neo4j 5Application:7474 / :7687--Knowledge graph: 5-layer model, APOC + n10s plugins
Neo4j SPE2Application:7475 / :7688--Secondary graph instance (federated profile)
Neo4j ProxyApplication:9090Neo4j, Control PlaneExpress bridge: FHIR/OMOP REST endpoints over Neo4j
Next.js UIApplication:3000 / :3003Neo4j ProxyPersona overviews, catalog, governance and exchange: 50 pages, 75 API routes
jad-seedSeed--All servicesOne-shot: phases 1-7 data seeding (Synthea, FHIR, OMOP, DSP)
GitHub PagesStatic--Next.js UI (static export)Public demo site with mock data fixtures

5. DSP Contract Negotiation

The Dataspace Protocol (DSP) governs how data holders and data users negotiate access to health datasets. The EHDS regulation adds HDAB approval as a pre-requisite for data permit issuance before contract negotiation can proceed.

Fig 4. DSP contract negotiation with EHDS compliance

6. Identity & Trust Framework

The Decentralized Claims Protocol (DCP) manages identity, credentials, and trust. Identity Hub stores DIDs and Verifiable Credentials, the Issuer Service mints EHDS-specific credentials, and Keycloak provides SSO/OIDC authentication.

Fig 5. DCP identity and trust architecture

7. SIMPL-Open & Compliance

This reference implementation aligns with the EU SIMPL-Open programme for federated data spaces. The architecture satisfies EHDS regulation, DSP 2025-1, DCP v1.0, and supply chain transparency requirements.

SIMPL-Open Alignment

  • DSP 2025-1: Sovereign data exchange via Control Plane
  • DCP v1.0: DID:web identity + Verifiable Credentials
  • Trust Framework: W3C Verifiable Credentials issued over DCP against the issuer's definitions
  • Federated Catalog: HealthDCAT-AP 2.1 metadata profiles (ADR-003)
  • SBOM: CycloneDX 1.5 supply chain transparency

Regulatory Compliance

  • EHDS Art. 3-12: Patient rights (access, rectification, portability)
  • EHDS Art. 50-51: Secondary use — HDAB approval, data permits
  • GDPR Art. 15-22: Data subject rights enforcement
  • EU CRA Art. 13: SBOM mandate, vulnerability disclosure
  • BSI C5: Cloud security baseline (DEV, OPS controls)

8. Architecture Decision Records

All 54 ADRs are maintained as standalone Markdown files in docs/ADRs/ .

ADR-001
PostgreSQL vs Neo4j Data Storage Split

Accepted

ADR-002
EDC Data Plane Architecture

Accepted

ADR-003
W3C HealthDCAT-AP Alignment

Accepted

ADR-004
Next.js 14 as Unified Frontend

Accepted

ADR-005
JAD + CFM Source Builds

Accepted

ADR-006
GHCR Image Publishing

Accepted

ADR-007
DID:web Resolution and DSP Contract Negotiation

Accepted

ADR-008
Comprehensive Testing Strategy

Accepted

ADR-009
IssuerService DCP Credential Issuance Fix

Accepted

ADR-010
WCAG 2.2 AA Accessibility Compliance

Accepted

ADR-011
Security Penetration Testing Strategy

Accepted

ADR-012
Azure Container Apps Deployment

Accepted

ADR-013
SIMPL-Open EU Programme Alignment

Accepted

ADR-014
Weekly Demo Environment Reset

Accepted

ADR-015
Single-VM Dev Deployment for Personal VS Subscription

Superseded

ADR-016
ACA Off-Hours Scale-Down

Superseded

ADR-017
Persistent Storage for Stateful Services on ACA

Accepted

ADR-018
24×7 Operation on INF-STG-EU_EHDS + Postgres-on-ACA Workaround

Accepted

ADR-019
Neo4j GDS + APOC + Azure AI Foundry for GraphRAG Accuracy

Accepted

ADR-020
Cross-Participant Dataset Discovery via Federated Catalog + NLQ

Accepted

ADR-021
Docling for AWMF Leitlinien PDF Ingestion (Layer 6)

Accepted

ADR-022
EDC Connector — Function vs Cost

Superseded

ADR-023
Reinstate Off-Hours ACA Scale-Down

Superseded

ADR-024
Full EDC Provisioning per Participant on Azure

Accepted

ADR-025
Keycloak Custom Domain (`auth.ehds.mabu.red`)

Accepted

ADR-026
Token-Efficient Planning & ADR Structure

Accepted

ADR-027
EDC Stack in Off-Hours Scale-Down (FinOps Cost Correction)

Superseded

ADR-028
Patient QR login via the EUDI Wallet (OpenID4VP)

Accepted

ADR-029
Dependency version pinning and refresh cadence

Accepted

ADR-030
Neo4j 5.26 → 2025.x calver line — migration readiness

Accepted

ADR-031
Every automated check must assert its outcome and exit non-zero on failure

Accepted

ADR-032
The API collection is organised by EHDS persona, and every request asserts its outcome

Accepted

ADR-033
Two-stage lab-report extraction: self-hosted parse, schema extraction, EU-resident models

Accepted

ADR-034
Reach the Claude API through workload identity federation, from a backend, never from the phone

Accepted

ADR-035
Azure EU by default, Anthropic by explicit consent, and the user's own provider without limit

Accepted

ADR-036
Operator secrets live in Azure Key Vault and are referenced, never copied

Accepted

ADR-037
A secure processing environment built on confidential computing, not on trust in the operator

Accepted

ADR-038
The scan is kept, as a sealed PDF, and diagnostics leave the phone only as a deliberate export

Accepted

ADR-039
Published reference ranges are quoted alongside the printed one, never in place of it

Accepted

ADR-040
Derived compliance state is computed in the API from the graph, never persisted

Accepted

ADR-041
Managed PostgreSQL on Azure, containerised PostgreSQL for local development

Accepted

ADR-042
Off-hours scale-down, the state that runs today

Accepted

ADR-043
UI routes read the graph directly; the proxy serves the data planes and what needs its credentials

Accepted

ADR-044
Every API route needs a session

Accepted

ADR-045
Cloud-native, vendor-agnostic observability, and a tamper-evident audit trail for regulators

Accepted

ADR-046
The Azure Vault keeps its state on the Flexible Server

Accepted

ADR-047
Vault stays up off-hours until it keeps its own state

Accepted

ADR-048
The TestFlight request is mailed by the hub, without a session

Superseded

ADR-049
Klarbefund connects to a patient's record by a device grant the website starts

Accepted

ADR-050
The Klarbefund beta is joined by a public TestFlight link

Proposed

ADR-052
The confidential secure processing environment, revisited against Azure and the vendors of October 2026

Proposed

ADR-053
Everything stops off hours, and the UI says so

Accepted

ADR-054
Klarbefund creates a sandbox account on the hub, gated by App Attest

Proposed

ADR-055
Azure runs the same JAD build as compose and CI

Accepted

Diagram Legend

■ Solid lines — direct data flow or API calls
■ Dashed lines — mapping / transformation relationships
● Subgraphs — logical boundary groupings
● Participants — protocol actors in sequence diagrams