Aller au contenu

Stratégie d'authentification GS-Apps

Vous êtes ici : Comprendre — comment on entre dans la suite (les flux d’authentification). Comprendre tous les flux d’authentification de GS-Apps — MSAL, OAuth PKCE, Managed Identity. Lecture 15 min. Audience : devs, auditeurs sécurité. Date : 2026-07-07 | Version : 1.2 — mise au gabarit Diátaxis ; retrait des identifiants internes (site public) ; apps alignées réalité juillet 2026 ; Système A (groups) marqué retiré — api-portail résout ses rôles en Système C (vérifié dans le code)

GS-Apps a un seul système d’autorisation en production (+ 2 historiques retirés) :

Système Pour quoi Statut
Azure AD claims groups (Système A) (retiré — api-portail porté en Système C) —
ug.UserAppRoles (Système B) (retiré 2026-06-22) —
ug.UserCompanyBcRoles (Système C) Source unique des rôles, multi-company En prod (admin, hub, inv, ug, portail)

Azure AD reste la source de vérité pour l’identité (qui tu es) ; l’autorisation (ce que tu as le droit de faire) vit en BD ug.

Flux scan QR publicUn signaleur scanne un sticker QR avec son téléphone personnel. Le navigateur appelle api-portail sur la page publique /p/QR. api-portail fait un SELECT des colonnes non-PII dans ptl.Stickers et renvoie une page HTML mobile rendue côté serveur. Aucune session utilisateur n’est créée.Signaleurtéléphone personnelapi-portailSSR mobile · publicptl.Stickerscolonnes non-PIIscan QR · GET /p/QR-…SELECT (non-PII)HTML mobileaucune session utilisateur — la page /p/:qrCode est publique
Le scan public : aucune authentification, aucune PII — seules les colonnes non sensibles de ptl.Stickers sont servies.

Aucune authentification requise. La page mobile /p/QR-XXXXX est publique.

Flux :

  1. Signaleur scanne sticker QR avec téléphone
  2. Browser → https://portail.groupesignalisation.ca/p/QR-00001
  3. api-portail → SQL SELECT sur ptl.Stickers (colonnes non-PII exposées publiquement)
  4. api-portail → SSR HTML mobile-first
  5. Signaleur clique « Santé et sécurité » → redirection vers l’intranet de Groupe Signalisation

Sécurité : aucune donnée personnelle sur la surface publique ; conformité Loi 25 pour cette zone — détail dans PUBLIC_VS_PRIVATE.md sur GitHub.

Cas 2 — Gestionnaire login via MSAL (apps existantes)

Section intitulée « Cas 2 — Gestionnaire login via MSAL (apps existantes) »
Flux MSAL — SPA ReactL’utilisateur ouvre une SPA React (hub, admin, inv ou ug). La SPA fait un loginRedirect ou une acquisition silencieuse vers Microsoft Entra ID, qui retourne un JWT avec l’audience API. La SPA envoie ce JWT en Bearer aux APIs internes, qui valident la signature et l’issuer puis résolvent les rôles dans ug.UserCompanyBcRoles.Microsoft Entra IDMFA par policySPA Reacthub · admin · inv · ugAPIs internesvalide signature · audience · issuerrôles : ug.UserCompanyBcRoles1 · loginRedirect2 · JWT (aud API)3 · Bearer JWT
Le flux MSAL des SPAs : connexion par redirection, JWT d’audience API, validation complète côté backend — les rôles viennent de la BD, pas du jeton.

Stack : MSAL.js navigateur + Azure AD + audience JWT partagée.

Flux :

  1. Gestionnaire ouvre https://hub.groupesignalisation.ca/
  2. SPA React détecte pas de session → MSAL loginRedirect() (pattern standard monorepo — éviter loginPopup() en prod)
  3. Azure AD prompt MFA si configuré → JWT retourné au browser
  4. Cache token MSAL + token aud=api://<client_id> envoyé en Bearer aux APIs
  5. APIs valident JWT (signature, audience, issuer v1+v2, expiration)
  6. Lookup ug.UserCompanyBcRoles pour autoriser/refuser

Sécurité : cache MSAL sécurisé, refresh silencieux, MFA par policy AAD.

Cas 3 — Gestionnaire/Admin sur Portail (OAuth PKCE)

Section intitulée « Cas 3 — Gestionnaire/Admin sur Portail (OAuth PKCE) »
Flux OAuth Authorization Code + PKCE (api-portail)L’utilisateur accède à api-portail par son navigateur. Le serveur SSR fait un échange Authorization Code avec PKCE auprès de Microsoft Entra ID, reçoit les tokens, et pose des cookies HttpOnly dans le navigateur de l’utilisateur.Utilisateurnavigateurapi-portailSSR · sans secret clientMicrosoft Entra IDredirectUri strictHTTPSAuth Code + PKCEtokenscookies HttpOnly · SameSite=Lax
Le flow OIDC d’api-portail : Authorization Code + PKCE (client public, sans secret), session ensuite portée par un cookie httpOnly.

Stack : OAuth Authorization Code + PKCE côté serveur Node.js (api-portail).

Pourquoi pas MSAL : api-portail est SSR (server-side), pas SPA. PKCE est le pattern moderne pour serveurs publics sans secret client.

Sécurité : PKCE-only, HTTPS forcé, cookies HttpOnly + SameSite=Lax, redirectUri strictement listé dans App Registration.

Cas 4 — Service-to-Service (Managed Identity SQL)

Section intitulée « Cas 4 — Service-to-Service (Managed Identity SQL) »
Flux Managed Identity vers Azure SQLLes apps Node (api-portail et les SPAs backend hub, admin, inv, ug) utilisent chacune leur Managed Identity system-assigned. La connexion SQL passe par le mode azure-active-directory-default vers Azure SQL GS_Apps — aucun mot de passe SQL dans la configuration.APPS NODEapi-portailhub · admin · inv · ugManaged Identitysystem-assigned · une par appazure-active-directory-defaultAzure SQLGS_Apps · zéro mot de passe
Service-to-service : chaque app Node porte sa Managed Identity ; le driver renouvelle les jetons tout seul. Détail : Managed Identity.

Stack : Managed Identity System-Assigned + tedious 16+ azure-active-directory-default.

Sécurité : aucun mot de passe SQL en App Settings pour GS_Apps ; MI scopée par app ; journalisation côté Azure (voir ADR-033).

Statut : RETIRÉ. Historiquement, api-portail dérivait le rôle des claims groups du JWT (trois groupes de sécurité Entra). Le portail a été porté en Système C : le rôle ne vient plus des groupes Azure AD, mais de ug.UserCompanyBcRoles (module Portail) — même source unique que les autres apps.

Aspect Système A (groups) Système B (ug.UserAppRoles) Système C (multi-company)
Source données Azure AD Azure SQL Azure SQL
Multi-company Non Non Oui
Granularité App-level App-level App × BC × Compagnie
Gestion Azure Portal UI (retiré) Console UG
Apps qui utilisent (aucune — retiré) (aucune — retiré) admin, hub, inv, ug, portail
Statut Retiré (portail porté en C) Retiré 2026-06-22 Prod — source unique

Stratégie de migration vers Système C — ✅ COMPLÉTÉE

Section intitulée « Stratégie de migration vers Système C — ✅ COMPLÉTÉE »

La fusion B→C et le retrait de ug.UserAppRoles sont livrés (2026-06-22), et api-portail — dernier utilisateur du Système A (groups) — a été porté en Système C. Toutes les apps en production résolvent leurs rôles dans ug.UserCompanyBcRoles.

État de la migration multi-companyug.UserAppRoles (Système B) est retiré. ug.UserCompanyBcRoles (Système C) est la source unique en production. Toutes les apps — admin, hub, inv, ug et portail — résolvent leurs rôles en Système C.ug.UserAppRolesSystème B — retiréug.UserCompanyBcRolesSystème C — prod, source uniqueToutes les appsles cinq apps en production
La migration est terminée : le Système C est l’unique source des rôles pour toutes les apps en production.
  1. Implémenter ug.UserCompanyBcRoles en BD ✅
  2. Migrer données depuis ug.UserAppRoles ✅ N/A (aucun utilisateur actif à migrer)
  3. Modifier les middlewares pour lire ug.UserCompanyBcRoles ✅ (2026-06-22)
  4. Retirer ug.UserAppRoles ✅ (Système B décommissionné)
  5. Porter api-portail (Système A → C) ✅ (le rôle vient de la BD, plus des groupes)
  6. Activer multi-company UG Phase 2+ (ADR-032)
Couches de défenseQuatre couches successives : l’identité (Azure AD avec MFA), l’authentification (MSAL, PKCE, Managed Identity), l’autorisation (Système C — la BD ug, source unique des rôles), puis l’audit, le réseau et les secrets.1 · IdentitéAzure AD + MFA (Conditional Access)2 · AuthentificationMSAL (SPA) · OAuth PKCE (SSR) · Managed Identity3 · AutorisationSystème C (BD ug) — source unique des rôles4 · Audit · réseau · secretsjournaux · HTTPS/VNet · zéro secret SQL
Quatre couches successives — une porte franchie n’ouvre jamais la suivante toute seule.
  1. Identité : Azure AD (MFA via Conditional Access)
  2. Authentification : MSAL.js (SPA) + OAuth PKCE (SSR portail) + Managed Identity (service)
  3. Autorisation : lookup BD ug (Système C — source unique des rôles)
  4. Audit : ptl.AccessLog (futur, ADR-032 §5) + Azure SQL Auditing (à activer)
  5. Réseau : HTTPS uniquement, VNet pour SOFI, NSG sortants
  6. Secrets : pas de mot de passe SQL GS_Apps en App Settings (migration MI 2026-04-27, ADR-033)

Loi 25 Québec

Art. 5 — accès limité. MI : identité par app, droits DB minimaux ; surface publique sans PII — SECURITY-SQL-ADMIN.md

ISO 27001

A.9.4 — accès privilégiés. ADR-033, fin du compte SQL administrateur partagé historique, break-glass documenté.

OWASP A04:2021

Insecure Design — OAuth PKCE, MI, pas de secret SQL en clair pour GS_Apps.