Sécurité

SMART App Launch expliqué : scopes, contextes de lancement, PKCE et le flux côté patient

SMART App Launch : spécification HL7 pour exécuter des apps sur tout serveur FHIR avec autorisation utilisateur. Inclut découverte, lancement EHR/autonome, flux code auth PKCE, scopes, contexte, tokens refresh, services backend, et nouveautés SMART v2 avec requêtes réelles.

par Publié 7 min de lecture

Réponse courte : SMART App Launch (SMART on FHIR) est la spécification HL7 décrivant comment une application obtient un accès autorisé à un serveur FHIR au nom d'un utilisateur. Il s'agit de OAuth 2.0 et OpenID Connect avec des conventions spécifiques à FHIR : un document de découverte à .well-known/smart-configuration ; deux modes de lancement (lancement EHR, où l'EHR ouvre l'application dans le contexte du patient actuel, et lancement autonome, où l'utilisateur ouvre l'application et choisit un patient) ; des scopes dans une syntaxe compatible FHIR (patient/Observation.rs signifie lire et rechercher les Observations du patient en contexte) ; un contexte de lancement renvoyé avec le token (quel patient, quel rendez-vous) ; et des services backend pour l'accès système à système avec authentification client JWT signée. SMART v2 (à partir de 2021) a rendu PKCE obligatoire, a ajouté des scopes granulaires et une authentification client asymétrique, et est la version requise par les programmes nationaux.

Étape 1 : découverte

La découverte du lancement d'application SMART commence par la récupération par l'application du document .well-known/smart-configuration du serveur FHIR. Ce document liste les points d'accès d'autorisation et de jeton, les fonctionnalités prises en charge (lancement depuis un DPI, lancement autonome, clients publics et confidentiels, OpenID Connect, autorisations patient et utilisateur), les scopes pris en charge, les méthodes de défi de code PKCE et les types d'octroi. Ainsi, l'application sait où envoyer l'utilisateur.

GET https://fhir.example-hospital.org/.well-known/smart-configuration
{
  "issuer": "https://auth.example-hospital.org",
  "authorization_endpoint": "https://auth.example-hospital.org/authorize",
  "token_endpoint": "https://auth.example-hospital.org/token",
  "introspection_endpoint": "https://auth.example-hospital.org/introspect",
  "capabilities": ["launch-ehr", "launch-standalone", "client-public", "client-confidential-asymmetric", "sso-openid-connect", "context-ehr-patient", "context-standalone-patient", "permission-patient", "permission-user", "permission-v2", "permission-offline"],
  "scopes_supported": ["openid", "fhirUser", "launch", "launch/patient", "patient/*.rs", "user/*.rs", "offline_access"],
  "code_challenge_methods_supported": ["S256"],
  "grant_types_supported": ["authorization_code", "client_credentials"]
}

L'application apprend où envoyer l'utilisateur et ce que le serveur prend en charge.

Étape 2 : lancement

Le lancement d'application SMART propose deux modes de lancement. Lors d'un lancement depuis un DPI, le clinicien ouvre l'application à l'intérieur du DPI, qui transmet un paramètre iss (le serveur FHIR) et un jeton de lancement opaque codant le patient et la rencontre actuels. Lors d'un lancement autonome, l'utilisateur ouvre l'application directement et le serveur d'autorisation lui demande de choisir ou de confirmer un patient.

Lancement EHR. Le clinicien clique sur l'application dans l'EHR ; l'EHR ouvre l'URL de lancement de l'application avec deux paramètres : iss (le serveur FHIR) et launch (un token opaque qui encode le patient et le rendez-vous actuels). L'application doit renvoyer launch dans sa requête d'autorisation avec le scope launch.

Lancement autonome. L'utilisateur ouvre l'application directement ; l'application connaît le serveur FHIR (choisi ou configuré) et demande le contexte avec launch/patient ; le serveur d'autorisation demande à l'utilisateur de choisir ou de confirmer un patient.

Étape 3 : code d'autorisation avec PKCE

L'étape d'autorisation SMART est le flux de code d'autorisation OAuth 2.0 avec PKCE : l'application redirige l'utilisateur vers le point d'accès d'autorisation avec ses scopes, l'audience (aud) du serveur FHIR et un défi de code. L'utilisateur s'authentifie et approuve. L'application échange le code retourné et le vérificateur de code contre un jeton d'accès qui arrive avec le contexte de lancement.

GET https://auth.example-hospital.org/authorize?
  response_type=code&client_id=my-app&redirect_uri=https://app.example.org/cb
  &scope=openid%20fhirUser%20launch%20patient/Observation.rs%20patient/Condition.rs%20offline_access
  &state=af0ifjsldkj&aud=https://fhir.example-hospital.org
  &launch=xyz123&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256

L'utilisateur s'authentifie (auprès du fournisseur d'identité de l'hôpital) et approuve les scopes ; le serveur redirige avec un code ; l'application l'échange :

POST https://auth.example-hospital.org/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=...&redirect_uri=https://app.example.org/cb&client_id=my-app&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
{
  "access_token": "eyJhbGciOi...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "openid fhirUser launch patient/Observation.rs patient/Condition.rs offline_access",
  "refresh_token": "a8c3...",
  "id_token": "eyJhbGciOi...",
  "patient": "Patient/123",
  "encounter": "Encounter/456",
  "fhirUser": "Practitioner/42",
  "need_patient_banner": true,
  "smart_style_url": "https://ehr.example.org/styles/smart.json"
}

Le contexte de lancement (patient, encounter, fhirUser) arrive avec le token. Les clients publics (applications mobiles et de navigateur) utilisent PKCE et aucun secret client ; les clients confidentiels s'authentifient avec un secret ou, de préférence, avec un JWT signé (private_key_jwt) selon la méthode asymétrique.

Scopes

Les scopes SMART on FHIR v2 utilisent la syntaxe contexte/ressource.permissions, où le contexte est patient, utilisateur ou système, et les permissions combinent c, r, u, d et s pour créer, lire, mettre à jour, supprimer et rechercher, comme dans patient/Observation.rs. Les scopes granulaires ajoutent un filtre, openid et fhirUser donnent l'identité de l'utilisateur, les scopes de lancement demandent le contexte, et offline_access demande un jeton de rafraîchissement.

Syntaxe SMART v2 : <contexte>/<ressource>.<permissions> où le contexte est patient (le patient en contexte), user (ce que l'utilisateur peut voir) ou system (backend), et les permissions sont c create, r read, u update, d delete, s search, dans cet ordre : patient/Observation.rs, user/Patient.rs, system/*.cruds. Les scopes granulaires ajoutent un filtre : patient/Observation.rs?category=http://terminology.hl7.org/CodeSystem/observation-category|vital-signs. openid fhirUser fournissent un ID token et l'identité FHIR de l'utilisateur ; launch, launch/patient, launch/encounter demandent le contexte ; offline_access un refresh token à utiliser lorsque l'utilisateur est absent, online_access un valable uniquement pendant la session. La syntaxe v1 (patient/Observation.read) est toujours acceptée par de nombreux serveurs.

Services backend

Pour un système qui agit sans utilisateur (une exportation nocturne, un moteur d'intégration), les Services Backend SMART utilisent client_credentials avec une assertion JWT signée (les clés publiques du client publiées à une URL JWKS) et des scopes system/. Pas d'utilisateur, pas de contexte de lancement, enregistrement strict.

Exécution en toute sécurité

Exécuter le lancement d'application SMART en toute sécurité signifie enregistrer des URI de redirection exacts, ne jamais utiliser le flux implicite, stocker et faire pivoter les jetons de rafraîchissement en toute sécurité, valider l'état (state) et l'audience (aud) des jetons d'identification, vérifier les jetons à chaque appel d'API, appliquer à la fois les scopes et le contexte patient au niveau des données afin qu'un jeton pour un patient ne lise jamais un autre, et enregistrer chaque accès.

Enregistrez des URI de redirection exacts ; n'utilisez jamais le flux implicite ; stockez les refresh tokens en toute sécurité et faites-les pivoter ; validez state ; vérifiez le aud des ID tokens ; vérifiez les tokens à chaque appel API (introspection ou validation JWT) et appliquez les scopes et le contexte patient au niveau des données, car un token pour Patient/123 ne doit jamais lire Patient/124 ; enregistrez chaque accès (Sécurité et identité : la carte). SMART définit également les Marques d'accès patient, un moyen pour les applications de montrer aux utilisateurs à quelles organisations elles peuvent se connecter, et interopère avec les Liens de santé SMART pour le partage initié par le patient.

Où il est requis

Les règles d'accès patient aux États-Unis exigent que les EHR certifiés prennent en charge SMART App Launch et les Services Backend ; les programmes nationaux en Europe l'adoptent pour l'accès aux applications (MedMij aux Pays-Bas utilise OAuth 2.0 avec des conventions équivalentes) ; l'IPS et de nombreux guides d'implémentation s'en servent. Voir TEFCA et Dossiers de santé électroniques nationaux.

Dans Anpheros

La plateforme Anpheros utilise OAuth 2.0 avec PKCE pour les applications et l'authentification client JWT signée pour les backends, avec des scopes dérivés du consentement de la personne et du contexte patient appliqué à chaque requête. Le site développeur documente l'authentification et le modèle backend SMART on FHIR pour y construire.

Pages connexes

Sources

Questions fréquentes

SMART on FHIR est-il identique à OAuth 2.0 ?

C'est OAuth 2.0 et OpenID Connect avec des ajouts spécifiques à FHIR : découverte, contexte de lancement, syntaxe des scopes et services backend. Toute bibliothèque OAuth fonctionne ; les conventions SMART sont ce qui rend une application portable sur différents serveurs FHIR.

Ai-je besoin de PKCE pour une application côté serveur ?

Dans SMART v2, oui, pour tous les clients utilisant le flux de code d'autorisation. Les clients confidentiels ajoutent l'authentification client (un secret ou un JWT signé) par-dessus.

Quelle est la différence entre les scopes patient/ et user/ ?

patient/ limite l'accès au patient unique dans le contexte de lancement ; user/ accorde ce que l'utilisateur authentifié est autorisé à voir, sur tous les patients. Les applications orientées patient utilisent patient/ ; les applications de clinicien utilisent souvent user/ avec contexte.

Une application SMART peut-elle écrire dans le dossier ?

Si les permissions de création ou de mise à jour (c, u) lui sont accordées dans ses scopes et que le serveur l'autorise. De nombreux déploiements accordent aux applications patient uniquement la lecture et la recherche, et acheminent les écritures via des ressources spécifiques telles que QuestionnaireResponse.

Anpheros Platform

Essayez gratuitement dans le sandbox

Votre premier appel FHIR en 5 minutes. Une API HL7 FHIR R4 avec le consentement du patient intégré : essayez-la dans le bac à sable, puis connectez votre propre application ou système de clinique.

Gratuit · 30 patients synthétiques · sans carte

Ce guide est informatif et ne remplace pas une consultation médicale. Pour toute décision concernant votre santé, parlez-en à votre médecin. En cas d’urgence, appelez le numéro d’urgence local (112 en Europe).
Rédigé par
L'équipe Anpheros

Anpheros développe un dossier médical que le patient contrôle et peut partager avec n'importe quelle clinique, sur une plateforme HL7 FHIR R4, basée en UE. Ces guides vous aident à comprendre et organiser votre santé ; ils ne remplacent pas votre médecin.

À propos d'Anpheros →