Koppelmij Implementation Guide
0.1.0 - ci-build

Koppelmij Implementation Guide - Local Development build (v0.1.0) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions

Option 2a - PGO als SMART on FHIR Resource Service

Optie 2: PGO als SMART on FHIR Resource Service met Token Exchange

Het probleem wat we oplossen is het feit dat in het launch proces de browser geauthenticeerd moet worden. Indien we dit niet doen, is het stelen van de launch request (POST of GET) een onacceptabel risico.

In deze optie fungeert het PGO als een SMART on FHIR resource service en gebruikt de bestaande PGO login sessie voor browser authenticatie. De module doorloopt een standaard SMART on FHIR app launch flow met het PGO, waarbij de PGO sessie wordt gevalideerd in de /authorize stap. Voor resource toegang gebruikt het PGO Token Exchange (RFC 8693) om namens de module een delegation token op te halen bij de DVA, waarbij de module zich authenticeert via RFC 7523 en dit token als actor_token wordt meegegeven.

Deze optie beschrijft een architectuur waarbij het PGO een dual-role vervult: enerzijds als SMART on FHIR authorization server voor de module, anderzijds als client voor de DVA. De browser authenticatie vindt plaats via de PGO sessie, en resource toegang wordt gefaciliteerd door Token Exchange. Op hoog niveau:

  • Het PGO doet het verzamelen en krijgt een access_token van de DVA
  • Het PGO fungeert als SMART on FHIR authorization server voor modules
  • De module start een SMART on FHIR flow met het PGO als authorization server
    • Browser authenticatie gebeurt via de bestaande PGO sessie in de /authorize stap
    • Module authenticeert zich via RFC 7523 (JWT Bearer assertion) in de /token stap
    • PGO doet Token Exchange met DVA tijdens de /token stap
  • Module krijgt access_token van PGO en kan direct DVA resources benaderen

Voordelen van deze PGO Authorization Server aanpak:

  • Hergebruik van PGO sessie: Geen extra authenticatie stappen nodig voor browser
  • Standaard SMART on FHIR: Module gebruikt bekende SMART launch flow
  • Delegation model: PGO handelt namens module met expliciete actor context
  • RFC compliance: Gebruikt RFC 8693 (Token Exchange) en RFC 7523 (JWT Bearer)
  • Veiligheid: Browser authenticatie via vertrouwde PGO omgeving
  • DPoP ondersteuning: Verplichte sender-constrained tokens via RFC 9449
  • Directe toegang: Module communiceert direct met DVA FHIR service
DVA Proces Flow Optie 2 DVA Proces Flow Optie 2PGO Proces Flow - PGO als SMART on FHIR Authorization Server met Token Exchange (met DPoP) ShortBrowserPGODVAModuleBrowserBrowserPGOPGODVADVAModuleModulePGO LoginLogin bij PGOPGO sessie actiefInitiële VerzamelingVerzamelen gegevensDigID authenticatieKrijgt access_tokenPGO slaat DVA access_token opvoor latere Token ExchangePGO Launch naar ModuleClick start module302 redirect naar module/launch?launch={launch_token}&iss={PGO_FHIR_URL}PGO genereert launch_tokengekoppeld aan PGO sessieGET/launch?launch=launch_tokenModule Start SMART on FHIR flow met PGOSMART on FHIR flow302 naar PGO/authorize(launch=launch_token&response_type=code)(front channel)Valideer PGO sessieCorreleer launch_tokenBrowser authenticatie viabestaande PGO sessie302{redirect_uri}?code=x&state=yGET{redirect_uri}?code=x&state=y/token(code=x&client_assertion viaRFC 7523)(backchannel)Token Exchange tijdens /token stapToken Exchange(subject_token=DVA_access_token)(actor_token=module_JWT_assertion)(backchannel)Delegation tokenaccess_token (gebaseerd opdelegation token)met aud veld:{DVA_URL}/fhirToken response bevat aud veldmet DVA FHIR resource service URLModule kan nu functionerenvia PGO met DVA resources

Hoofdstappen van het proces

1. Initiële PGO login

De gebruiker logt in bij zijn Persoonlijke Gezondheidsomgeving (PGO) PGO maakt een sessie-status aan en bindt deze aan de PGO-sessie PGO configureert zich als SMART on FHIR authorization server Dit vormt het startpunt voor toegang tot digitale interventies

2. Verzamelen van gegevens

PGO vraagt DVA (Dienstverlener Aanbieder) om gegevens te verzamelen DVA laat gebruiker inloggen via DigID voor authenticatie Na succesvolle authenticatie krijgt DVA toegang en geeft een access_token terug aan PGO PGO gebruikt dit token om FHIR-taken op te halen van DVA PGO slaat DVA access_token op voor latere Token Exchange operaties Opmerking: Dit is een OIDC (OpenID Connect) flow tussen PGO en DVA

3. Module launch naar PGO

Gebruiker klikt op "start module" in PGO PGO genereert eigen launch token en stuurt gebruiker door naar module PGO doet 302 redirect naar module met launch parameter:

  • GET {MODULE_URL}/launch?launch={launch_token}&iss={PGO_FHIR_BASE_URL}

4. SMART on FHIR Authorization Flow

4a. /authorize stap (front-channel):

  • Module redirects browser naar PGO /authorize endpoint met launch parameter
  • GET {PGO_URL}/authorize?response_type=code&client_id={module_id}&redirect_uri={module_redirect}&launch={launch_token}&state={module_state}
  • PGO valideert bestaande browser sessie (geen nieuwe login nodig)
  • PGO correleert launch_token met PGO sessie
  • Na validatie: redirect naar module met authorization code

4b. /token stap (back-channel):

  • Module doet /token request naar PGO met authorization code
  • Module authenticeert zich via RFC 7523 JWT Bearer assertion met verplichte cnf claim voor DPoP
  • PGO voert tegelijkertijd Token Exchange uit met DVA:
    • grant_type=urn:ietf:params:oauth:grant-type:token-exchange
    • subject_token=DVA_access_token (uit stap 2)
    • actor_token=module_JWT_assertion (uit RFC 7523 authenticatie, bevat cnf claim)
    • requested_token_type=urn:ietf:params:oauth:token-type:access_token
  • DVA extraheert cnf claim uit actor_token JWT voor DPoP key binding
  • DVA genereert DPoP delegation token met module als actor context
  • PGO geeft module een DPoP access_token (gebaseerd op delegation token) en DVA FHIR endpoint informatie

5. Module functioneren

Module gebruikt DPoP access_token voor directe FHIR requests naar DVA Module communiceert rechtstreeks met DVA FHIR service Browser blijft geauthenticeerd via originele PGO sessie Module moet DPoP proof meesturen bij elk direct DVA API request Module kan functioneren met DVA resources via directe DVA interactie

Technische flow details

Launch stap:

  • Module endpoint: {MODULE_URL}/launch
  • Parameters: launch={launch_token}&iss={PGO_FHIR_BASE_URL}
  • Method: 302 redirect of FORM_POST_REDIRECT
  • Launch token: Opaque waarde gegenereerd door PGO, gekoppeld aan PGO sessie

SMART on FHIR tussen Module en PGO:

  • Authorization endpoint: {PGO_URL}/authorize
  • Token endpoint: {PGO_URL}/token
  • FHIR endpoint: Verwijst naar {DVA_URL}/fhir (module gaat direct naar DVA)
  • Launch parameter: Gebruikt in /authorize voor sessie correlatie
  • Module gebruikt RFC 7523 voor client authenticatie in /token stap
  • DPoP verplicht: Module moet cnf claim in JWT client assertion opnemen

Token Response Specificatie:

  • Het token response van de SMART on FHIR /token request bevat een aud veld met de DVA FHIR resource service URL
  • Het aud veld bevat de waarde {DVA_URL}/fhir om de beoogde audience van het token aan te geven
  • Dit is een extra veld buiten de standaard SMART on FHIR en OIDC specificaties
  • Voorbeeld token response:
    {
      "access_token": "...",
      "token_type": "DPoP",
      "expires_in": 3600,
      "scope": "...",
      "aud": "{DVA_URL}/fhir"
    }
    

Token Exchange tussen PGO en DVA (tijdens PGO /token stap):

  • Exchange endpoint: {DVA_URL}/token
  • Subject token: DVA access_token van PGO (uit verzamelen fase)
  • Actor token: Module JWT assertion (uit RFC 7523 authenticatie, bevat cnf claim)
  • cnf claim extractie: DVA haalt cnf claim uit actor_token JWT voor DPoP key binding
  • Resultaat: DPoP delegation token voor DVA resources
  • DPoP tokens: Altijd gebonden aan module's publieke sleutel via cnf claim uit JWT

Directe Module-DVA communicatie:

  • Module gebruikt DPoP delegation token voor directe requests naar {DVA_URL}/fhir
  • Geen PGO tussenkomst bij FHIR API calls
  • DVA valideert DPoP delegation token en actor context
  • DVA valideert DPoP proof bij elke request

Browser authenticatie:

  • Launch stap: Browser wordt door PGO naar module gestuurd
  • /authorize stap: Gebaseerd op bestaande PGO sessie
  • Launch token correlatie: PGO koppelt launch_token aan sessie
  • Geen extra login stappen voor gebruiker
  • Veilige correlatie via PGO session management

DPoP Token specifieke aspecten:

  • cnf claim: Zit in module's JWT client assertion, bevat JWK thumbprint van module's publieke sleutel
  • DPoP proof: Module moet bij elk direct DVA API request een DPoP proof JWT meesturen
  • Key binding: Token is cryptografisch gebonden aan module's private key
  • Replay protection: DPoP proof bevat timestamp en nonce voor replay-resistance
DVA Proces Flow Optie 2 DVA Proces Flow Optie 2PGO Proces Flow - PGO als SMART on FHIR Authorization Server met Token Exchange (met DPoP)BrowserPGODVAModuleDigIDDVA_fhirBrowserBrowserPGOPGODVADVAModuleModuleDigIDDigIDDVA_fhirDVA_fhirlogin at PGOloginPGO sessie actiefverzamelenverzameleninloggencredentialsid_tokenaccess_tokenPGO slaat DVA access_token opvoor latere Token Exchange operatiesget FHIR taskstaskslaunch voorbereidingclick start modulecreate launch_token and bindit to the PGO sessionLaunch token gekoppeld aan PGO sessievoor latere correlatie tijdens /authorizelaunch naar module met SMART on FHIR302 redirect naar module/launch?launch={launch_token}&iss={PGO_FHIR_BASE_URL}GET/launch?launch=launch_token&iss=PGO_FHIR_URLgenereer DPoP key pairvoor sender-constrainedtokensModule genereert verplicht DPoP key pairvoor beveiliging via RFC 9449302 naar PGO authorizationendpoint/authorize?response_type=code&client_id={module_id}&redirect_uri={module_redirect}&launch={launch_token}&state={module_state}validate PGO sessioncorrelate launch_token withsessionBrowser authenticatie via bestaande PGO sessieGeen nieuwe login nodig302{redirect_uri}?code=x&state=yGET{redirect_uri}?code=x&state=yPOST /tokencode=x&client_assertion={JWTvia RFC 7523 met cnf claim}&grant_type=authorization_code(backchannel)Module authenticeert zich via RFC 7523 JWT Bearer assertioncnf claim in JWT bevat JWK thumbprint voor DPoPToken Exchange tijdens PGO /token stap (met DPoP)Token Exchange Request/token?grant_type=urn:ietf:params:oauth:grant-type:token-exchange&subject_token={DVA_access_token}&actor_token={module_JWT_assertionmet cnf claim}&requested_token_type=urn:ietf:params:oauth:token-type:access_token(backchannel)RFC 8693 Token Exchange voor delegation tokenPGO gebruikt DVA access_token als subject_tokenModule JWT assertion (met cnf claim) als actor_tokencnf claim in JWT voor DPoP key bindinggenerate DPoP delegationtokenwith module context and keybindingfrom cnf claim in actor_tokenJWTToken Exchange Responseaccess_token (DPoPdelegation token)token_type=DPoP, expires_inToken Responseaccess_token (DPoPdelegation token)token_type=DPoP, id_tokenaud: {DVA_URL}/fhirModule krijgt DPoP delegation token voordirecte FHIR requests naar DVAAltijd DPoP type voor extra beveiligingToken response bevat aud veld met DVA FHIR URLmodule functionerencreate DPoP proof JWT(ath, jti, htm, htu, iat)DPoP proof bevat verplicht:- ath: access token hash- jti: unique identifier- htm: HTTP method- htu: HTTP URI- iat: timestampFHIR requestsAuthorization: DPoP{delegation_token}DPoP: {DPoP_proof_JWT}validate DPoP delegationtokenen DPoP proofFHIR responseModule communiceert direct met DVAmet DPoP delegation token uit Token ExchangeVerplichte DPoP beveiliging via key binding