Managed Identity — le passwordless par application
Vous êtes ici : Référence — l’identité des applications elles-mêmes. Comment les apps se connectent à SQL et au Storage sans aucun secret — une identité par unité de déploiement. Lecture 8 min. Audience : devs, auditeurs sécurité. Date : 2026-07-07 | Version : 1.0 — remplace le stub (matière : code
@gs/db/@gs/storage, bicep, migrations,docs/standards/AUTH.md, ADR-033/057/060/065)
| Question | Réponse |
|---|---|
| Un mot de passe SQL quelque part ? | Non — SQL_USE_MANAGED_IDENTITY=true posé par l’infrastructure, connexion azure-active-directory-default |
| Qui renouvelle les jetons ? | Le driver (tedious + DefaultAzureCredential) à chaque connexion physique du pool — zéro code maison |
| Quelle identité pour qui ? | Apps web : system-assigned (une chacune) ; worker ETL : user-assigned dédiée ; Storage : même principe, SAS user-delegation |
| Et côté base ? | CREATE USER … FROM EXTERNAL PROVIDER versionné en migrations — permissions as code |
| Tout est en MI ? | Non — trois exceptions assumées : SOFI (système externe, compte dédié lecture seule), le CI d’initialisation BD, le dev local |
1. Le problème réglé à la racine
Section intitulée « 1. Le problème réglé à la racine »Historiquement, les applications partageaient un compte SQL à privilèges élevés, mot de passe en clair dans la configuration — l’anti-pattern classique des premiers déploiements (rotation pénible, fuite possible par logs ou capture d’écran, aucune traçabilité par application). La migration Managed Identity (ADR-033, avril 2026) a remplacé ce partage : chaque application se présente à la base sous son propre nom, et les journaux SQL savent qui fait quoi.
2. Comment ça marche
Section intitulée « 2. Comment ça marche »- L’infrastructure (module Bicep unique des apps) crée l’App Service avec son identité (
SystemAssigned) et poseSQL_USE_MANAGED_IDENTITY=true— c’est une convention d’infrastructure, pas un choix par app. - Le connecteur SQL (
@gs/db) ouvre le pool en modeazure-active-directory-default: le driver obtient un jeton Entra viaDefaultAzureCredentialà chaque connexion physique du pool, et le renouvelle tout seul. - En développement local, la même config retombe sur un compte SQL classique — branche explicitement étiquetée dev only.
3. Qui a quelle identité
Section intitulée « 3. Qui a quelle identité »| Unité | Identité | Pourquoi |
|---|---|---|
| Apps web (hub, admin, ug, inv, mcp, api-portail) | System-assigned, une par app | Cycle de vie lié à l’app ; provisionnée par le module Bicep unique (ADR-065) |
Worker ETL (gs-etl-worker) |
User-assigned dédiée, partagée par ses deux jobs (file + horaire) et par le déclencheur de file | L’ETL a sa propre identité — jamais celle d’une app web (fin du cumul de privilèges historique de l’app admin) |
Accès Storage (@gs/storage) |
Même identité que l’app appelante, via DefaultAzureCredential |
Aucune clé de compte ; URLs signées en SAS user-delegation (dérivées du jeton Entra, plafonnées à 7 jours) — ADR-057 |
4. Côté base — permissions as code
Section intitulée « 4. Côté base — permissions as code »L’identité ne suffit pas ; il faut lui accorder des droits, et ces droits sont du code (ADR-060) :
- Chaque identité est créée en base par une migration versionnée —
CREATE USER … FROM EXTERNAL PROVIDERidempotent, suivie deGRANTexplicites (exemple : la Console UG reçoitSELECT, INSERT, UPDATEsur son schéma — pasDELETE, le soft delete étant la règle). - Un manifeste canonique décrit qui a le droit de toucher quel schéma, avec les exceptions documentées et justifiées (ex. : l’outil MCP reste lecteur global par conception — il consulte tout schéma présent et futur, borné en lecture seule par un garde SQL).
- Un contrôle de dérive en CI compare l’état réel de la base au manifeste.
5. Ce qui n’est pas en Managed Identity (assumé)
Section intitulée « 5. Ce qui n’est pas en Managed Identity (assumé) »| Exception | Pourquoi |
|---|---|
| SOFI (ERP source) | Système externe hors d’Azure — compte dédié lecture seule, secrets injectés par l’infrastructure, jamais dans le dépôt |
| CI d’initialisation BD | Le pipeline db:init utilise un compte SQL dédié (le DDL exige des privilèges qu’aucune MI runtime ne doit porter) ; la cible versionnée est un principal fédéré OIDC — pas encore provisionné |
| Dev local | Compte SQL classique, branche explicitement dev only |
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Stratégie d’authentification — le Cas 4 (service-to-service) dans le paysage global.
- Sécurité — la posture passwordless dans son ensemble.
- Architecture de données — la convention de connexion unique et son test de contrat.
- ADR-033 — Managed Identity SQL