Toegang tot Epic in Mendix
Leestijd: ± 7 minuten
Context
Data-uitwisseling in de zorg is lastig. Laat staan als het om patiëntgegevens gaat. De zorg heeft dit probleem nog niet opgelost. De zorg heeft er wel een verzameling standaarden aan toegevoegd.
Epic, een van de grootste EPD’s in de VS en met een groeiende aanwezigheid in Nederland, lost dat op met een generieke API-laag: hetzelfde toegankelijke, gestandaardiseerde formaat voor al hun klanten, gebaseerd op HL7 FHIR (Fast Healthcare Interoperability Resources). Resources zoals Patient, Observation, Condition en Encounter hebben daardoor overal dezelfde structuur en een voorspe lbaar URL-patroon. In Nederland komt daar de nl-core-profilering van de zibs (Zorginformatiebouwstenen) nog bovenop; de volgende blog in deze serie gaat daar specifiek over.
Zorginstellingen bouwen graag een IT-landschap rond hun EPD: patiëntportalen, planningstools, rapportagedashboards, eigen zorgapplicaties. Dat landschap heeft pas waarde als die systemen daadwerkelijk bij de patiëntdata kunnen. Mendix is daar een geschikt platform voor, mits de connectie naar het EPD geregeld is. MxBlue heeft voor Epic die connectie gebouwd: de Epic Connector.
De connector regelt de authenticatie. De data zelf ontsluit vervolgens mogelijkheden zoals een dashboard dat ’s nachts automatisch labwaarden ophaalt uit Epic, of een integratie die periodiek patiëntgegevens synchroniseert, zonder dat daar een ingelogde gebruiker aan te pas komt. Dit blog gaat over hoe die authenticatie werkt, wat de Epic Connector daarvan automatiseert en welke scope die module dekt.
Hoe authenticatie bij Epic werkt
Een gewone REST API beveilig je met een API key of een gedeeld geheim. Je stuurt credentials mee, de server controleert ze en je bent klaar. Voor server-to-server communicatie waarbij meerdere onafhankelijke partijen met dezelfde dienst communiceren, is dat een onprettige eigenschap. Een gedeeld geheim is geen geheim: zodra het lekt, is er geen manier om te achterhalen bij wie.
Epic schrijft voor backend-integraties SMART Backend Services voor, gebaseerd op RFC 7523 (de OAuth 2.0-standaard voor client-authenticatie met een ondertekende JWT in plaats van een gedeeld secret). Het centrale principe is dat jouw applicatie zijn identiteit bewijst via een cryptografische handtekening in plaats van via een wachtwoord. Er bestaat daardoor geen gedeeld geheim dat gestolen of gelekt kan worden. Dat kost meer infrastructuur dan een API key, maar levert er iets voor terug: elke partij is individueel identificeerbaar, en een sleutel intrekken raakt alleen die partij.
Het mechanisme werkt als volgt. Je genereert een RSA keypair. De private key bewaar je server-side, nooit blootgesteld. De public key publiceer je als JWKS-document op een URL die publiek bereikbaar is over HTTPS. Bij Epic registreer je je applicatie met die URL; Epic haalt de public key op en slaat hem op.
Per authenticatieverzoek stel je een JWT samen met claims die beschrijven wie je bent, wanneer het token verloopt en voor welk endpoint het bedoeld is. Je ondertekent de JWT met je private key. Epic ontvangt de JWT, haalt de bijbehorende public key op via je JWKS-endpoint, verifieert de handtekening en geeft een access token terug. Met dat token doe je vervolgens je FHIR-aanroepen.

Wat je hiervoor nodig hebt als je dit zelf bouwt:
- een RSA keypair, gegenereerd server-side
- een correct geformatteerd JWKS-endpoint, publiek bereikbaar over HTTPS
- logica om per aanroep een geldige JWT samen te stellen en te signeren
- een strategie voor key rotation, want een private key die nooit wordt vervangen is een risico dat langzaam groter wordt
dit alles per omgeving, want sandbox en productie gebruiken aparte app-registraties en aparte sleutels
Dit is beheersbaar als je het één keer goed inricht. Het is beduidend minder beheersbaar als je het per project opnieuw bedenkt.
Wat de Epic Connector doet
De Epic Connector is een Mendix Marketplace-module die de infrastructuurlaag uit de vorige sectie voor zijn rekening neemt: alles wat nodig is om toegang te krijgen tot Epic-data. De FHIR-data zelf, en wat je ermee doet, blijft aan de ontwikkelaar.
Key management via de admin UI
Vanuit de meegeleverde pagina’s genereer je een RSA keypair. De private key wordt opgeslagen als versleutelde FileDocument via de JWT-module en verlaat de applicatie nooit. De public key wordt automatisch gepubliceerd op het JWKS-endpoint, standaard bereikbaar op /rest/epic-connector/v1/jwks. Je registreert die URL bij Epic en de connector regelt de rest.
Configuratie in database-entities, niet in constants
Constants vereisen een herdeployment bij omgevingswisseling. Database-entities niet. Per omgeving configureer je een EpicBackendConfig-record met client ID, token endpoint en FHIR base URL; geen nieuwe release nodig om van sandbox naar productie te gaan.
Token ophalen via één microflow
SUB_OAuthToken_Get_Epic verzorgt het volledige authenticatieproces: JWT samenstellen, signeren, inleveren bij het token endpoint, access token ophalen. De microflow slaagt of gooit een fout. Er is geen tussentoestand. Do, or do not. There is no try.
FHIR-aanroepen
FHIRResource_RetrieveByReference haalt één resource op met type en ID. FHIRResource_Search doet een zoekaanroep met een query string voor elk resourcetype naar keuze. Het resultaat is een FHIRResource-entiteit met de FHIR JSON en metadata zoals versie en LastUpdated. Typed entities voor Patient, Observation, Condition en Encounter komen via de FHIRMapper-module, die naast de connector bestaat en in een volgende blog aan bod komt.
Key rotation
Een nieuwe KeyMaterial activeren via de admin UI markeert de oude sleutel als inactief. Die sleutel blijft nog 24 uur zichtbaar in de JWKS: de tijd die Epic nodig heeft om zijn cache te verversen. Daarna verwijder je hem. De overgang is non-breaking.
Wat overblijft na deze vijf onderdelen is de applicatielogica: wat je met de opgehaalde FHIR-resources doet en hoe je ze vertaalt naar typed entities via de FHIRMapper. Dat is het onderwerp van de volgende blog.
Security als ontwerpbeslissing
In een module die met patiëntdata werkt, is het de moeite waard om expliciet te maken welke security-keuzes zijn gemaakt en waarom.
- Private keys verlaten de applicatie niet: gegenereerd via de JWT-module, opgeslagen als versleutelde FileDocument, blootgesteld door geen enkel endpoint, log of interface.
- Het JWKS-endpoint publiceert uitsluitend de publieke helft van actieve keypairs.
- Token logging staat standaard uit: access tokens worden niet naar de Mendix-log geschreven. Handig bij het debuggen, minder handig bij een datalek.
- KeyMaterial en EpicBackendConfig horen achter Administrator-niveau roles en zijn niet bedoeld voor reguliere gebruikers.
Alle vier volgen uit het ontwerp van de module. Ze zijn de default en vragen geen extra configuratie.
Scope
De connector richt zich op backend-to-backend communicatie met Epic: een Mendix-applicatie die met Epic praat zonder dat er een ingelogde gebruiker in het spel is. Denk aan geautomatiseerde data-imports, klinische dashboards of integraties waarbij Epic-data wordt verrijkt met eigen applicatielogica.
Buiten scope:
- user-context flows, waarbij een individuele gebruiker zich aanmeldt via Epic en de applicatie namens hem handelt
- andere EPD-systemen
- consent management
- access control binnen de eigen applicatie
De connector richt zich op de toegangslaag naar Epic. Wat daarna met de data gebeurt, is aan de ontwikkelaar. Vanaf hier is het jouw probleem, in de best mogelijke zin van het woord.
Conclusie
De Epic Connector regelt de authenticatie voor backend-toegang tot Epic: RSA keypairs, een JWKS-endpoint, JWT’s die je per aanroep signeert volgens SMART Backend Services. Dat is infrastructuur die je anders zelf moet bouwen, testen en onderhouden, per omgeving opnieuw. En dat gebeurt met beveiliging als uitgangspunt, niet als checklist die je achteraf afvinkt.
Wat je met de opgehaalde data doet, is aan jou. De vertaling naar typed entities zoals Patient en Observation gebeurt via de FHIRMapper-module, het onderwerp van de volgende blog.
Zorginstellingen die een IT-landschap rond hun EPD willen bouwen, hebben daarmee een manier om dat vanuit Mendix te doen zonder zelf een authenticatiemechanisme te hoeven ontwerpen.
Auteur: Stephan Wolbers – Head of Technology & Innovation MxBlue|SUPERP