Le coffre du bureau des douanes
Sur un port à conteneurs, il existe un bureau où l'on ne range rien d'utile. Pas de marchandise, pas de palettes. Des scellés numérotés, les clés des conteneurs frigorifiques, et les certificats d'origine qui prouvent qu'un chargement est bien ce qu'il prétend être.
Ce bureau ne produit rien. Il garde. Et son intérêt tient à une seule règle : personne ne repart avec le coffre. On présente son badge, on obtient l'objet dont on a besoin, et le registre note qui est venu, quand, pour quoi.
La règle tombe le jour où un grutier recopie la combinaison sur un carnet pour aller plus vite. Le coffre est toujours là, verrouillé, parfaitement inutile.
Côté Azure, c'est exactement ce qui se passe quand une chaîne de connexion se retrouve dans un fichier de configuration versionné. Le service de coffre est déployé, il facture, il ne protège rien.
La sécurité applicative dans le cloud ne consiste pas à ajouter un service de plus. Elle consiste à retirer quelque chose : le secret que quelqu'un a écrit quelque part.
Les quatre gestes
Le sujet paraît vaste. Il tient en quatre gestes, qui s'enchaînent dans cet ordre.
Ne jamais écrire un secret. Il vit dans un coffre, versionné, avec une date d'expiration et un journal d'accès. L'application le lit au démarrage ou à l'usage, elle ne le stocke pas.
Prouver son identité sans mot de passe. L'application porte une identité délivrée par la plateforme, et elle obtient des jetons de courte durée. Il n'y a plus rien à faire fuir.
Chiffrer. La donnée au repos est déjà chiffrée par défaut ; la vraie décision porte sur celui qui détient la clé. Celle en transit l'est aussi, à condition d'imposer un plancher.
Retirer les services de données de l'Internet public. Un compte de stockage ou une base joignable depuis n'importe où reste joignable même quand tout le reste est propre.
App Service ou conteneur"] --> I["Identité managée
jeton de courte durée"] I --> V["Key Vault
secrets, clés, certificats"] I --> D[("Donnée
stockage, base")] V -->|"clé de chiffrement"| D P["Point de terminaison privé
et zone DNS privée"] -.-> V P -.-> D classDef app fill:#ede9e1,stroke:#8a4d16,color:#1f2428; classDef ident fill:#b5651d,stroke:#8a4d16,color:#f5f2ec; classDef donnee fill:#d89253,stroke:#8a4d16,color:#2c3338; class A app; class I,V ident; class D,P donnee;
Les trois premiers gestes protègent l'accès. Le quatrième protège contre l'accès qu'on n'avait pas prévu.
Ces quatre gestes se conçoivent ensemble. Un coffre irréprochable derrière une base ouverte sur l'Internet public déplace le problème sans le traiter.
Key Vault, trois tiroirs et deux modèles d'autorisation
Le coffre du bureau des douanes range trois choses différentes, et la différence compte.
Azure Key Vault aussi. Un secret est une chaîne opaque : mot de passe hérité, jeton d'un partenaire, chaîne de connexion d'un logiciel tiers. Une clé est un objet cryptographique, RSA ou courbe elliptique, utilisé pour signer ou chiffrer. Un certificat est un objet composite, un certificat X.509 accompagné de sa clé privée, avec un cycle de vie et un renouvellement automatisables.
La distinction structurante est ailleurs. Un secret sort du coffre : l'application en reçoit la valeur en clair. Une clé n'en sort pas : on envoie l'opération au coffre, et c'est le résultat qui revient. Le scellé reste dans le bureau, on apporte le document à tamponner.
| Objet | Ce qu'on y met | Ce qui sort du coffre | Rôle intégré associé |
|---|---|---|---|
| Secret | Mot de passe, jeton, chaîne de connexion héritée | La valeur, en clair, dans le processus | Key Vault Secrets User en lecture, Key Vault Secrets Officer en gestion |
| Clé | Clé de chiffrement ou de signature | Jamais la clé, seulement le résultat de l'opération | Key Vault Crypto User en usage, Key Vault Crypto Officer en gestion |
| Certificat | Certificat X.509 et sa clé privée | Le certificat, la partie privée suivant la règle des clés | Key Vault Certificates Officer |
Le coffre existe en deux niveaux de service : un niveau standard, et un niveau supérieur où les clés sont protégées par un module matériel. Pour les contextes réglementés qui exigent un pool matériel dédié et une administration séparée, il y a un service distinct, le module matériel managé, avec son propre modèle de rôles.
Stratégies d'accès ou RBAC
Historiquement, un coffre s'autorisait par stratégies d'accès : une liste de principaux, chacun avec ses permissions par type d'objet. C'est local au coffre, non hiérarchique, et invisible depuis la gouvernance générale des accès.
Le modèle RBAC applique au contenu du coffre les mêmes rôles, la même portée et le même héritage que le reste d'Azure, avec en prime la possibilité d'attribuer un rôle sur un objet précis plutôt que sur le coffre entier. C'est le modèle recommandé aujourd'hui, et le seul qui se gouverne avec les outils décrits dans RBAC, accès conditionnel et PIM.
Le piège classique est la confusion entre plan de gestion et plan de données. Administrer un coffre et lire son contenu sont deux droits distincts. Avec les stratégies d'accès, quiconque peut modifier la configuration du coffre peut s'ajouter une stratégie et lire les secrets ; avec RBAC, il faut aussi le droit d'attribuer des rôles.
Ce qui se règle une fois pour toutes
La suppression réversible est active par défaut et ne se désactive pas : un objet supprimé reste récupérable pendant une période de rétention configurable. La protection contre le vidage empêche de purger avant la fin de cette période, et une fois activée elle ne se retire plus. C'est volontaire : elle existe pour résister à celui qui possède les identifiants d'administration.
La rotation se conçoit au moment de la création, pas après le premier incident. Les clés acceptent une politique de rotation automatique. Les secrets, eux, portent des dates d'activation et d'expiration, et la notification envoyée à l'approche de l'échéance peut déclencher un traitement qui régénère l'identifiant chez son fournisseur.
Enfin, un coffre ne produit aucun journal tant qu'un paramètre de diagnostic n'a pas été posé pour envoyer sa catégorie d'audit vers un espace de travail. La règle posée dans Supervision : Azure Monitor, Log Analytics et alertes s'applique ici sans exception.
Dernier point de conception : un coffre par application, par environnement et par région. La portée d'un coffre est aussi un rayon de souffle, et les quotas de service s'apprécient par coffre.
Un coffre n'est pas un magasin de configuration. Les paramètres non sensibles vont dans un service de configuration applicative ; y mélanger le reste rend le journal d'accès au coffre illisible.
L'identité managée de bout en bout
Sur le port, le grutier ne connaît aucune combinaison. Il présente son badge au bureau des douanes, qui vérifie son habilitation du jour et lui remet ce dont il a besoin. Son badge expire, il ne se recopie pas sur un carnet.
C'est le rôle d'une identité managée. La ressource Azure reçoit une identité dans l'annuaire, la plateforme lui délivre des jetons de courte durée via un point de terminaison local, et le code n'embarque plus aucun identifiant.
Deux formes coexistent. L'identité affectée par le système naît et meurt avec la ressource, une seule par ressource. L'identité affectée par l'utilisateur est une ressource à part entière, réutilisable par plusieurs services, et surtout stable dans le temps.
Cette stabilité tranche souvent la question. Si l'application est recréée à chaque déploiement, l'identité affectée par le système disparaît avec elle, et ses attributions de rôle sont à recréer une par une. L'identité affectée par l'utilisateur survit au redéploiement.
Le câblage tient en trois commandes, et la troisième est celle qu'on bâcle.
# une identité réutilisable, indépendante du cycle de vie de l'application
az identity create --name id-facturation --resource-group rg-facturation-prod
# on la rattache à l'application web
az webapp identity assign --name app-facturation --resource-group rg-facturation-prod \
--identities "$IDENTITY_ID"
# lecture des secrets du coffre, et rien d'autre
az role assignment create \
--assignee-object-id "$PRINCIPAL_ID" --assignee-principal-type ServicePrincipal \
--role "Key Vault Secrets User" \
--scope "$VAULT_ID"
Côté code, la bibliothèque d'identité enchaîne les sources d'authentification disponibles : variables d'environnement en développement, identité managée en exécution. Le même binaire tourne des deux côtés sans configuration conditionnelle.
var credential = new DefaultAzureCredential();
// aucun secret dans le code, la configuration ou le dépôt
var secrets = new SecretClient(new Uri("https://kv-facturation-prod.vault.azure.net/"), credential);
KeyVaultSecret cleTransporteur = await secrets.GetSecretAsync("cle-api-transporteur");
// pour un service Azure, il n'y a même plus de secret à aller chercher
var blobs = new BlobServiceClient(new Uri("https://stfacturationprod.blob.core.windows.net"), credential);
Reste le cas des chaînes de connexion héritées, celles d'un progiciel qui ne sait rien faire d'autre. On ne renonce pas pour autant : il suffit de ne jamais recopier la valeur. Une référence au coffre dans les paramètres d'application, ou un pilote qui monte le secret dans le conteneur au démarrage. La valeur reste alors dans un seul endroit, où elle se tourne et se révoque.
Deux détails d'exploitation, souvent découverts en production : l'attribution d'un rôle n'est pas visible instantanément, et une identité managée s'authentifie très bien tout en n'ayant aucun droit. Un accès refusé après un déploiement est presque toujours une attribution manquante, pas un problème de jeton.
Une identité managée ne supprime pas le contrôle d'accès, elle supprime le secret. Le droit reste à attribuer explicitement, sur la bonne portée, avec le rôle le plus étroit qui fasse le travail.
Chiffrer, et savoir qui tient la clé
L'entrepôt sous douane garde les marchandises sous scellé. La question intéressante n'est jamais de savoir si le scellé existe, mais qui détient le sceau et qui peut le retirer.
Sur Azure, la donnée au repos des services de stockage est chiffrée par défaut, sans intervention, et ce chiffrement ne se désactive pas. La décision de conception porte donc sur la détention de la clé.
| Modèle | Qui détient la clé | Ce que ça change vraiment | Ce que ça coûte en exploitation |
|---|---|---|---|
| Clés gérées par la plateforme | Le fournisseur | Rien à faire, rotation assurée par le service | Nul |
| Clés gérées par le client | Vous, dans un coffre ou un module matériel managé | Vous pouvez rendre la donnée illisible en retirant l'accès à la clé | Cycle de vie et rotation à piloter, disponibilité du coffre devenue critique |
| Clés fournies par le client | Vous, en dehors d'Azure | La clé accompagne l'appel et n'est pas conservée par le service | La clé voyage à chaque requête, sa garde vous incombe entièrement |
| Chiffrement côté client | Vous, dans l'application | Le service ne voit jamais la donnée en clair | Recherche, index et traitements côté service perdus |
Le modèle des clés gérées par le client mérite un avertissement. Le service accède à la clé par une identité managée et un rôle dédié ; le coffre qui l'héberge doit avoir la suppression réversible et la protection contre le vidage. Supprimer cette clé ou couper cet accès rend la donnée inexploitable, ce qui est précisément la fonctionnalité recherchée et le risque assumé.
Pour les machines virtuelles, trois mécanismes se superposent et répondent à des menaces différentes : le chiffrement côté serveur des disques managés, actif par défaut, le chiffrement sur l'hôte qui couvre aussi le disque temporaire et le cache, et le chiffrement dans le système invité qui protège le volume tel que l'invité le voit.
En transit, tout se joue sur un plancher. Un compte de stockage peut n'accepter que le HTTPS, et la version minimale de TLS se paramètre sur le compte comme sur une application web. Le chiffrement du transport authentifie le serveur, pas l'appelant : il ne remplace ni le jeton ni le rôle.
Une clé gérée par le client ne protège pas de l'attaquant qui détient déjà l'accès applicatif. Elle donne un interrupteur : le jour où l'on retire la clé, ce qui reste sur le disque cesse d'être lisible.
Sortir de l'Internet public
Un quai relié à la voie publique est accessible à tout véhicule qui se présente, badge ou pas. Le retirer de la voie publique et le raccorder par une voie de service interne change la nature du problème : il n'y a plus de portail à défendre en permanence.
Un point de terminaison privé est une carte réseau posée dans votre sous-réseau, avec une adresse privée, associée à une ressource précise et à une sous-ressource précise. Un compte de stockage en demande un par service exposé : le blob et le fichier ne partagent pas le même point d'entrée.
| Service | Sous-ressource cible | Zone DNS privée |
|---|---|---|
| Key Vault | vault |
privatelink.vaultcore.azure.net |
| Stockage, service blob | blob |
privatelink.blob.core.windows.net |
| Azure SQL Database | sqlServer |
privatelink.database.windows.net |
| Service Bus et Event Hubs | namespace |
privatelink.servicebus.windows.net |
| Registre de conteneurs | registry |
privatelink.azurecr.io |
Le contrôle le plus souvent oublié est la deuxième étape. Créer un point de terminaison privé n'interdit pas l'accès public : les deux chemins coexistent tant qu'on ne ferme pas le premier explicitement.
resource coffre 'Microsoft.KeyVault/vaults@2023-07-01' = {
name: 'kv-facturation-prod'
location: location
properties: {
sku: { family: 'A', name: 'standard' }
tenantId: subscription().tenantId
enableRbacAuthorization: true
enableSoftDelete: true
enablePurgeProtection: true
publicNetworkAccess: 'Disabled'
networkAcls: { defaultAction: 'Deny', bypass: 'AzureServices' }
}
}
La troisième étape est le DNS, et c'est elle qui provoque les tickets. Le nom public de la ressource reste le nom utilisé par les applications ; sans zone DNS privée liée au réseau virtuel, il continue de résoudre vers l'adresse publique et le trafic ignore la voie interne. Depuis un site raccordé en hybride, il faut en plus un redirecteur qui ramène la résolution du côté Azure, sujet traité dans Réseau virtuel : adressage, appairage et connectivité hybride.
Le coût, enfin, se planifie. Un point de terminaison consomme une adresse par ressource et par sous-ressource, ce qui se chiffre vite sur une flotte et se prévoit dans le plan d'adressage.
Un point de terminaison privé qui fonctionne se vérifie en trois questions : le nom résout-il vers une adresse privée, l'accès public est-il refusé, et un test depuis l'extérieur échoue-t-il vraiment.
Ce que la plateforme signale, et le dernier secret qui traîne
Defender for Cloud
Le service évalue en continu la configuration des ressources et la restitue sous forme de recommandations regroupées en contrôles, avec un score de sécurité. Sa valeur ici est pratique : il repère les coffres sans protection contre le vidage, les comptes de stockage ouverts, les ressources joignables publiquement, les autorisations trop larges.
Des plans payants s'ajoutent par type de ressource, avec de la détection de menaces sur les serveurs, le stockage, les conteneurs, les bases et les gestionnaires de clés. Le socle gratuit de recommandations suffit à faire le ménage initial ; les plans répondent à une autre question, celle de la détection en cours d'attaque.
La chaîne de livraison
Une fois les quatre gestes appliqués, il reste presque toujours un secret quelque part : celui que la chaîne d'intégration continue utilise pour se connecter à Azure et déployer.
La connexion de charge de travail fédérée le supprime. La plateforme d'intégration présente un jeton signé par son propre émetteur, l'annuaire le valide au regard de l'émetteur et du sujet déclarés à l'avance, et rend un jeton d'accès. Rien n'est stocké, donc rien n'est à faire tourner.
permissions:
id-token: write
contents: read
steps:
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
Les trois valeurs restantes sont des identifiants publics, pas des secrets. Le point délicat se déplace vers la déclaration du sujet fédéré : elle doit désigner le dépôt et la branche attendus, faute de quoi un autre dépôt obtient les mêmes droits.
Le dernier secret d'une plateforme est presque toujours dans son outil de déploiement. C'est aussi celui qui a les droits les plus larges.
Scénario B : la clé de signature de Storm-0558
En juillet 2023, Microsoft a rendu public l'accès d'un acteur qu'il désigne sous le nom de Storm-0558 à des boîtes aux lettres Exchange Online, chez une vingtaine d'organisations et plusieurs centaines de personnes, dont des responsables gouvernementaux américains. Le Cyber Safety Review Board, instance rattachée au département américain de la sécurité intérieure, a publié en 2024 un rapport détaillé sur cette intrusion.
Le mécanisme n'est pas un mot de passe cassé. L'attaquant disposait d'une clé de signature du système d'identité grand public de Microsoft, avec laquelle il a forgé des jetons d'accès. Un jeton fabriqué de cette manière n'est pas volé à une victime : il est valide, correctement signé, et le service qui le reçoit n'a aucune raison de le rejeter.
Deux défauts se sont additionnés. La clé était ancienne, datée de 2016, et n'avait pas été remplacée, la rotation automatique de ces clés ayant été suspendue à la suite d'un incident de disponibilité provoqué par une rotation précédente. Et un défaut de validation a permis à des jetons signés dans le domaine grand public d'être acceptés pour des comptes d'entreprise, deux domaines qui auraient dû rester étanches.
La façon dont cette clé est sortie du périmètre de l'éditeur n'était pas établie au moment de la publication du rapport. Microsoft a exposé de son côté, en septembre 2023, son hypothèse principale : un vidage mémoire produit lors d'un incident sur un système de signature aurait contenu la clé, puis aurait quitté le réseau de production vers un environnement de débogage.
La détection, elle, n'est pas venue du fournisseur. Elle est venue d'un client, un organisme fédéral américain, qui exploitait les journaux détaillés d'accès aux boîtes aux lettres et avait écrit ses propres règles d'analyse. À la suite de l'incident, Microsoft a annoncé l'élargissement de l'accès à des journaux d'audit jusque-là réservés aux niveaux de licence supérieurs. Le conseil, pour sa part, a jugé l'intrusion évitable.
Quatre transpositions directes pour une application ordinaire. Une clé qui ne tourne pas finit par fuir, et la rotation doit être conçue avant la mise en production, avec des consommateurs capables d'accepter deux versions pendant la bascule. Une clé qui ne quitte jamais un module matériel ne se retrouve pas dans un vidage mémoire, ce qui est exactement la promesse du tiroir « clés » d'un coffre. Le cloisonnement se décide au départ : un coffre par application et par environnement, une clé par usage. Et un accès qui n'est pas journalisé ne se raconte pas après coup.
La bonne question n'est pas de savoir si le coffre est sûr. C'est de savoir si, demain matin, on peut dire quelle identité a lu quel secret la semaine dernière, et depuis quand cette clé n'a pas changé.
Points clés
- Les quatre gestes s'enchaînent : pas de secret écrit, une identité managée à la place, une décision explicite sur qui détient les clés de chiffrement, et des services de données retirés de l'Internet public.
- Dans Key Vault, un secret sort du coffre et une clé n'en sort pas. Choisir le bon tiroir change le niveau de protection réel, avant même de parler d'autorisations.
- Le modèle RBAC est celui qui aligne le coffre sur la gouvernance des accès du reste de la plateforme ; la suppression réversible et la protection contre le vidage sont ce qui le rend résistant à un administrateur compromis.
- Un point de terminaison privé ne ferme pas la porte publique et ne configure pas le DNS. Les trois étapes se font ensemble, sinon la voie interne n'est jamais empruntée.
- Le dernier secret d'une plateforme vit dans sa chaîne de déploiement, et une connexion fédérée le supprime au lieu de le faire tourner.
Dans la série
Palier 3 : Faire tourner le port. Domaine : Applications & intégration.
- Précédent : Infrastructure applicative : messagerie, passerelle d'API et cache
- Suivant : Haute disponibilité : SLA, zones, régions et basculement
- Vue d'ensemble : Concevoir sur Azure : par où commencer
Pour aller plus loin
- RBAC, accès conditionnel et PIM : donner le bon accès, pour la portée, l'héritage et le moindre privilège appliqués aux rôles utilisés ici.
- Réseau virtuel : adressage, appairage et connectivité hybride, pour le plan d'adressage et la résolution de noms dont dépendent les points de terminaison privés.
- Vue d'ensemble d'Azure Key Vault et le guide RBAC du coffre, pour les rôles et les portées disponibles.
- Suppression réversible et protection contre le vidage, le paramètre qui décide de ce qui se passe après une suppression accidentelle ou malveillante.
- Identités managées pour les ressources Azure, pour les deux formes et les services qui les prennent en charge.
- Azure Private Link et la configuration DNS des points de terminaison privés, avec la liste des zones par service.
- Chiffrement du service de stockage et clés gérées par le client, pour le détail des modèles de détention de clé.
- Connexion de charge de travail fédérée, pour supprimer le secret de la chaîne de livraison.
- Rapport du Cyber Safety Review Board sur l'intrusion de l'été 2023 dans Exchange Online, publié en 2024 et disponible sur le site de la CISA, ainsi que les publications du centre de réponse aux incidents de sécurité de Microsoft sur l'acquisition de la clé, référence du scénario B.