SPIFFE : une identité stable pour des applications en constante évolution
Donner aux applications et aux services une identité vérifiable, indépendante de ce qui change en permanence dans leur environnement d'exécution — la seconde fondation Zero Trust de nos projets.
Dans notre précédent article, eBPF prenait la forme d'un tourniquet placé au plus près des échanges entre applications. Un tel contrôle ne prend toutefois tout son sens qu'à la condition de savoir quel badge reconnaître — et de pouvoir s'assurer qu'il appartient bien à celui qui le présente.
Dans Kubernetes, les composants qui exécutent une application sont par nature éphémères. Les Pods disparaissent et renaissent, leurs adresses changent, leur nombre varie au rythme de la charge et des déploiements. Au milieu de ce mouvement permanent, une chose doit pourtant demeurer stable : l'identité du service, son rôle et les droits qui lui sont associés.
C'est précisément ce que propose SPIFFE : donner aux applications et aux services une identité vérifiable, indépendante autant que possible de ce qui, dans leur environnement d'exécution, ne cesse de changer — une adresse IP, un conteneur ou une machine.
Le principe paraît simple. Sa mise en œuvre l'est beaucoup moins. Il faut attribuer le bon badge au bon service, le renouveler sans interrompre les échanges, puis veiller à ce qu'il cesse d'ouvrir des portes dès lors que les droits associés disparaissent.
Ce que SPIFFE permet, concrètement
SPIFFE est un ensemble de spécifications destiné à donner une identité vérifiable aux applications et aux services, que le standard désigne sous le terme de workloads. Il peut s'agir d'un service, d'un processus ou, plus largement, d'un composant exécuté dans un environnement distribué.
Dans la métaphore de notre bâtiment, SPIFFE définit le badge. Celui-ci permet de reconnaître le service qui se présente, indépendamment de son adresse IP, de son conteneur ou de la machine qui l'héberge.
SPIFFE répond ainsi à une première question : qui se présente ? Les règles d'autorisation déterminent ensuite ce qu'il peut faire. Un badge authentique n'ouvre donc pas toutes les portes.
Le badge doit survivre au remplacement de l'instance
Dans Kubernetes, un Pod peut disparaître puis être recréé quelques secondes plus tard. La nouvelle instance peut recevoir une autre adresse IP, être exécutée sur un autre nœud et, pendant un déploiement, cohabiter temporairement avec celle qu'elle remplace.
Pour l'utilisateur, rien n'a véritablement changé : il s'agit toujours de la même application. Pour l'infrastructure, en revanche, presque tout a changé.
L'identité ne peut donc pas rester attachée à une instance particulière. Elle doit suivre le rôle du service et être retrouvée par la nouvelle instance, sans pour autant pouvoir être récupérée par un autre composant qui viendrait occuper sa place.
Cette stabilité ne signifie pas que le badge reste identique dans le temps. L'identité logique du service peut demeurer constante, tandis que les éléments cryptographiques utilisés pour la prouver sont, eux, renouvelés régulièrement.
C'est là que se joue une part importante de la continuité de service. Si une application légitime ne parvient plus à obtenir ou à renouveler son identité, elle peut perdre l'accès à ses dépendances. À l'inverse, une identité attribuée au mauvais composant peut permettre à celui-ci de se présenter comme un service reconnu.
L'enjeu n'est donc pas seulement de conserver une identité stable dans un environnement mouvant. Il consiste surtout à garantir, dans le temps, que cette identité reste associée au bon service.
Un badge n'a de valeur que s'il est remis au bon service
Un badge n'a de valeur que si le système qui le délivre sait précisément à qui il le remet.
Dans une architecture dynamique, cette étape est déterminante. Avant d'attribuer une identité, le système doit s'assurer que le composant qui la demande correspond bien au service qu'il prétend représenter. Cette vérification s'appuie sur plusieurs informations issues de l'orchestrateur, de l'environnement d'exécution et du système lui-même.
Une erreur à ce stade ne se limite pas à produire un badge incorrect. Elle peut donner à une application une identité que le reste de l'architecture considérera comme parfaitement légitime. Le risque change alors de nature. Il ne s'agit plus seulement de protéger une clé, un secret ou un certificat, mais de garantir la fiabilité de toute la chaîne qui relie une application à l'identité qui lui est attribuée.
Cette chaîne doit également rester lisible. Lorsqu'une identité est utilisée, il faut pouvoir retrouver le service concerné, comprendre dans quelles conditions elle a été délivrée et déterminer le périmètre dans lequel elle devait être reconnue.
Car une identité techniquement fiable, mais impossible à rattacher clairement à une application ou à un service métier, apporte finalement peu à l'analyse d'un incident — et guère davantage à l'audit.
Les transitions mettent la confiance à l'épreuve
Les éléments qui permettent à une application de prouver son identité ont une durée de vie limitée. Ils doivent donc être renouvelés régulièrement, sans interrompre le fonctionnement du service.
Cette rotation réduit le temps pendant lequel une identité ancienne ou compromise peut rester exploitable. Elle introduit toutefois une contrainte supplémentaire : faire évoluer la confiance sans rompre les communications qu'elle protège.
Un renouvellement tardif peut suffire à interrompre les échanges d'une application pourtant légitime. Une transition mal synchronisée peut, de son côté, conduire deux composants à ne plus reconnaître temporairement les mêmes autorités. À l'inverse, une identité encore valide peut subsister alors même que les droits associés au service viennent d'être modifiés.
Ces écarts apparaissent notamment lorsqu'un service change de rôle, quitte un environnement ou perd l'accès à une dépendance. Le badge peut encore être authentique alors que la porte ne devrait plus s'ouvrir. La situation inverse est tout aussi problématique : le service conserve ses droits, mais ne parvient plus à présenter une identité reconnue.
Dans un cas, le risque concerne la sécurité ; dans l'autre, la disponibilité.
C'est précisément dans ces moments de transition que notre expérimentation devient la plus intéressante. Le fonctionnement nominal montre que deux services savent se reconnaître. Les renouvellements, les redémarrages, les changements de rôle ou les retraits d'autorisation permettent, eux, d'observer ce qui se passe lorsque la confiance doit évoluer sans que le système s'arrête.
Un domaine de confiance n'est pas un droit d'accès
SPIFFE organise les identités au sein de domaines de confiance. Chacun d'eux constitue un périmètre dans lequel les identités sont établies et vérifiées à partir d'une même racine de confiance.
C'est ici qu'intervient SPIRE, l'une des principales implémentations de SPIFFE. Il fournit l'infrastructure chargée d'établir ces identités, de les délivrer aux workloads et d'administrer le domaine de confiance auquel elles appartiennent.
Dans notre bâtiment, le domaine de confiance correspond à l'autorité qui délivre les badges et permet d'en vérifier l'authenticité. Reconnaître cette autorité ne signifie toutefois pas que tous les badges qu'elle émet ouvrent les mêmes portes.
Cette distinction devient essentielle lorsque plusieurs clusters, environnements ou organisations doivent communiquer. Une plateforme de production n'expose pas les mêmes risques qu'un environnement de développement ; de la même manière, une identité issue d'un partenaire ou d'un autre cluster ne doit pas nécessairement bénéficier du même niveau de confiance qu'une identité interne.
Rendre l'identité exploitable
Une identité cryptographiquement vérifiable ne suffit pas à rendre une architecture intelligible. Sa valeur dépend aussi de la manière dont elle est reprise par les applications, les mécanismes de sécurité et les outils d'observation. Un même service ne devrait pas apparaître successivement sous des adresses, des noms techniques ou des certificats difficiles à rapprocher.
Cette cohérence prend toute son importance lors d'un incident. Une identité inconnue, un document expiré, une autorisation refusée ou une communication interrompue peuvent produire des symptômes proches, tout en renvoyant à des causes très différentes.
L'identité doit alors permettre de reconstituer les échanges : identifier les services concernés, retrouver les identités utilisées et comprendre les règles qui ont conduit à accepter ou à refuser une communication.
SPIFFE fournit ainsi une base commune pour nommer et authentifier les applications. Sa valeur apparaît pleinement lorsque cette identité peut être reliée aux règles appliquées et aux événements observés.
Une seconde fondation pour nos projets
Avec eBPF, nous avons exploré le tourniquet : le point où une communication peut être observée ou contrôlée au plus près du système.
Avec SPIFFE, nous travaillons sur le badge présenté à ce tourniquet : une identité qui doit rester cohérente alors que l'application change d'instance, de machine ou d'environnement.
Ces deux expérimentations traitent de problèmes différents, mais complémentaires. L'identité indique quel service se présente. Les règles définissent ce qu'il peut atteindre. Les contrôles appliquent ces décisions sur un périmètre déterminé. L'observation doit ensuite permettre d'expliquer ce qui s'est réellement produit.
Le badge et le tourniquet ne prennent leur sens qu'ensemble. C'est dans la cohérence entre l'identité, l'autorisation, le contrôle des échanges et les contraintes d'exploitation que se construisent les fondations Zero Trust de nos applications.
Lectures complémentaires
Services associés