Un cluster Kubernetes exécutant des microservices de défense n'est pas intrinsèquement zero-trust. Le modèle de réseau par défaut des pods permet à n'importe quel pod d'initier une connexion TCP vers n'importe quel autre pod sur le même réseau de cluster, ce qui signifie qu'un seul conteneur compromis peut atteindre des services d'authentification, des banques de données et des interfaces de commandement auxquels il n'a aucune raison légitime d'accéder. Un service mesh résout ce problème non pas en reconfigurant les ACL réseau — qui sont fragiles dans les environnements de conteneurs dynamiques — mais en insérant l'identité cryptographique et l'application des politiques directement dans le chemin de données de chaque appel service à service. Cet article examine ce que cela signifie concrètement pour les clusters de défense : comment SPIFFE/SPIRE s'intègre à l'architecture zero-trust pour les réseaux militaires, comment la politique basée sur l'intention remplace la pensée périmétrique à l'intérieur du cluster, et comment maintenir une observabilité complète sans qu'aucune télémétrie ne franchisse la limite de classification.

Pourquoi la sécurité périmétrique échoue dans les clusters de microservices de défense

Le modèle de sécurité périmétrique suppose que le trafic à l'intérieur d'une limite réseau de confiance est sûr. Dans une application monolithique, cette hypothèse a une certaine validité : il y a un seul processus, une seule frontière de confiance et relativement peu de chemins de communication internes à sécuriser. Dans une architecture de microservices déployée sur Kubernetes, l'hypothèse s'effondre totalement. Un cluster exécutant 20 services présente de l'ordre de 400 paires de services possibles. Toutes ne devraient pas communiquer, mais sans application explicite au niveau du service, elles le peuvent toutes. Une vulnérabilité dans un service — une dépendance avec une faille d'exécution de code à distance, une variable d'environnement mal configurée exposant des identifiants, une image de base non corrigée — donne à un adversaire la capacité de se déplacer latéralement à travers l'ensemble du réseau de cluster.

Le mode de défaillance n'est pas théorique. Les compromissions de chaîne d'approvisionnement ciblant les charges de travail en conteneurs ont démontré qu'une fois qu'un adversaire dispose d'une exécution de code dans un pod, il sonde agressivement le réseau de cluster. Sans authentification mutuelle, rien n'empêche le pod compromis d'appeler directement des API internes : il dispose déjà d'une IP de cluster valide, ses requêtes arrivent depuis une plage CIDR de confiance, et le service cible n'a aucun moyen de vérifier l'identité de l'appelant. La segmentation réseau traditionnelle via Kubernetes NetworkPolicy aide au niveau IP/port mais ne prévient pas l'usurpation de l'identité d'un pod légitime dans la plage d'adresses autorisée, et n'applique aucune contrainte au niveau applicatif sur les opérations permises.

Un service mesh résout cela en rendant obligatoire l'identité cryptographique de charge de travail pour chaque connexion. Chaque proxy sidecar présente un SPIFFE Verifiable Identity Document (SVID) — un certificat X.509 de courte durée encodant l'identité du compte de service du pod — et exige que le sidecar distant présente un SVID valide en retour avant que des données applicatives ne circulent. La vérification d'identité se produit au niveau de la couche de transport, de manière transparente pour l'application, et ne peut pas être contournée par un attaquant qui ne contrôle que le processus applicatif à l'intérieur du conteneur. Le déplacement latéral est réduit de « atteindre n'importe quel pod sur le réseau de cluster » à « atteindre uniquement les pods dont la politique autorise explicitement votre SVID comme source ».

Choisir un service mesh : Istio vs Linkerd vs Cilium dans les environnements air-gappés

Trois implémentations de service mesh sont viables en production pour les déploiements Kubernetes de défense, chacune avec un profil de compromis différent. Istio est le plus complet en fonctionnalités : son plan de données basé sur Envoy prend en charge une gestion riche du trafic L7 comprenant l'injection de pannes, les nouvelles tentatives, le disjoncteur, la mise en miroir des requêtes et les AuthorizationPolicy à grain fin. Le plan de contrôle — istiod — s'intègre nativement avec SPIFFE/SPIRE pour l'émission de certificats externe, et son pipeline de télémétrie émet des métriques et traces compatibles OpenTelemetry depuis chaque sidecar. Le coût est la complexité opérationnelle : Istio a une courbe d'apprentissage plus raide, une empreinte de plan de contrôle plus importante, et des sidecars Envoy qui consomment plus de mémoire par pod que les alternatives. Pour les clusters disposant de 16 Go ou plus de RAM par nœud et des équipes expérimentées avec la configuration Envoy, l'expressivité des politiques d'Istio est difficile à égaler.

Linkerd adopte l'approche opposée. Son proxy de plan de données est écrit en Rust et conçu pour être ultra-léger : chaque sidecar linkerd-proxy utilise 10 à 20 Mo de mémoire résidente et ajoute moins de 1 ms de latence à chaque saut, contre 50 à 100 Mo et 0,5 à 3 ms pour Envoy. Le mTLS sans configuration de Linkerd est activé par défaut pour tout le trafic maillé sans nécessiter de manifeste PeerAuthentication, ce qui réduit le risque d'une exception en texte clair mal configurée. Le compromis est que le modèle de politique de Linkerd est moins expressif au niveau de la méthode HTTP et du chemin, et que son plan de contrôle s'intègre moins directement avec les émetteurs SPIRE externes qu'Istio. Pour les clusters edge contraints en ressources avec une RAM limitée par nœud, l'efficacité du proxy de Linkerd constitue un avantage opérationnel significatif.

Cilium opère au niveau de la couche eBPF plutôt qu'en tant que sidecar. En intégrant l'application des politiques dans les programmes eBPF du noyau Linux attachés à l'interface réseau de chaque pod, Cilium atteint une surcharge quasi nulle par charge de travail pour l'application des politiques réseau et le mTLS de base. Sa ressource CiliumNetworkPolicy prend en charge les règles tenant compte de l'identité SPIFFE grâce à l'intégration avec l'API SPIRE, et le composant d'observabilité Hubble fournit une visibilité des flux L4/L7 au sein du cluster. La force de Cilium réside dans ses performances et son remplacement transparent de kube-proxy ; sa limitation est que l'application des politiques HTTP/gRPC L7 via eBPF est moins mature que l'équivalent basé sur Envoy d'Istio pour les scénarios d'autorisation complexes. En pratique, de nombreux clusters de défense exécutent Cilium en tant que CNI pour la politique réseau et le chiffrement, avec Istio ou Linkerd superposés pour l'observabilité L7 et les AuthorizationPolicy à granularité fine au niveau des services.

mTLS mutuel : émission de certificats, rotation et intégration SPIFFE/SPIRE

Le mTLS mutuel dans un service mesh signifie que les deux côtés de chaque connexion s'authentifient mutuellement avec des certificats X.509 avant l'échange de données applicatives. La question critique pour un déploiement de défense est de savoir comment ces certificats sont émis, à quelle fréquence ils pivotent et qui contrôle la racine de confiance. Istio natif utilise sa propre autorité de certification intégrée (l'AC istiod), qui émet des certificats de charge de travail valides pour 24 heures par défaut. Pour un déploiement de défense, cela est insuffisant à deux égards : la clé racine réside à l'intérieur du cluster (un processus istiod compromis expose toutes les identités de charge de travail), et des TTL de 24 heures sont trop longs pour les environnements où une révocation rapide des identifiants peut être requise.

SPIRE fournit l'architecture correcte pour les contextes de défense. Le serveur SPIRE s'exécute en tant que StatefulSet avec son bundle de confiance et ses entrées d'enregistrement persistés dans un datastore pouvant être maintenu en dehors du cluster. L'agent SPIRE s'exécute en tant que DaemonSet sur chaque nœud et gère l'attestation de charge de travail en vérifiant le jeton de compte de service Kubernetes de chaque pod auprès du serveur d'API avant d'émettre un SVID. Les SVID émis ont des TTL configurables — les déploiements de défense en production utilisent des TTL d'une heure pour les charges de travail standard et des TTL de 15 minutes pour les charges de travail traitant des données classifiées — et l'agent SPIRE gère la rotation automatiquement, transmettant un nouveau SVID au socket de charge de travail avant l'expiration du SVID actuel. Le sidecar du mesh lit le SVID via le socket de l'API de charge de travail SPIFFE et le présente sur toutes les connexions TLS sortantes sans aucune modification du code applicatif.

L'intégration de SPIRE avec Istio nécessite de configurer istiod pour utiliser SPIRE comme fournisseur de certificats via l'interface de plugin d'autorité de certification en amont. La configuration CustomCA d'Istio pointe istiod vers le port GRPC du serveur SPIRE, déléguant toute l'émission et la rotation des SVID à SPIRE tandis qu'Istio gère l'application des PeerAuthentication et AuthorizationPolicy. Cette séparation des préoccupations est importante : SPIRE possède le cycle de vie de l'identité (attestation, émission, rotation), tandis qu'Istio possède le cycle de vie des politiques (quelles identités peuvent communiquer sur quels chemins). Un opérateur révoquant l'accès d'une charge de travail supprime son entrée d'enregistrement SPIRE, ce qui fait échouer la prochaine rotation de SVID, coupant la charge de travail du mesh lors du prochain renouvellement de certificat sans nécessiter de modifications des manifestes de politique.

Politique de trafic basée sur l'intention : liste d'autorisation des communications est-ouest

Le principe de refus par défaut exige qu'aucun trafic service à service ne soit autorisé sauf s'il est explicitement permis par une politique. Dans Istio, cela est implémenté avec un manifeste AuthorizationPolicy à l'échelle du cluster ayant un bloc de règles vide et action : DENY — qui bloque tout le trafic — suivi de politiques d'autorisation étroites pour chaque paire de services légitime. Chaque politique d'autorisation nomme le principal source (l'URI SPIFFE du compte de service du service appelant), le service de destination et l'ensemble précis des méthodes HTTP ou noms de services gRPC autorisés pour l'appel. Une politique autorisant un service d'ingestion de données de capteur à effectuer des requêtes POST vers l'API de fusion de données, par exemple, ne l'autorise pas également à effectuer des requêtes GET d'enregistrements historiques ou à appeler le point de terminaison d'administration, même si les deux s'exécutent sur le même port de service de destination. La granularité est au niveau de l'opération, pas seulement au niveau de la connexion TCP.

La rédaction et la maintenance de ce jeu de politiques exigent de la rigueur. Un cluster qui passe de 10 à 30 services sur 18 mois accumule des centaines d'entrées d'autorisation, et les entrées obsolètes pour les services décommissionnés deviennent une surface d'attaque latente. Deux pratiques préviennent cette accumulation. Premièrement, traiter les manifestes AuthorizationPolicy comme du code : les stocker dans le même dépôt versionné que les manifestes applicatifs, exiger une révision par les pairs pour chaque nouvelle entrée d'autorisation, et auditer le jeu de politiques trimestriellement par rapport à la liste des services en cours d'exécution. Deuxièmement, utiliser la journalisation des accès du mesh — chaque requête refusée génère une entrée de journal d'accès dans le sidecar incluant le SVID source, la destination et l'opération — pour identifier les chemins de trafic légitimes sans politique plutôt que de contourner silencieusement le mesh. Cette journalisation fournit également la piste d'audit requise par de nombreux cadres de sécurité de défense pour démontrer que les décisions de contrôle d'accès sont auditables.

Point clé : La mauvaise configuration la plus courante dans les déploiements zero-trust de service mesh est l'application du PeerAuthentication en mode PERMISSIVE pendant la période de migration sans jamais achever le passage au mode STRICT. En mode PERMISSIVE, les connexions TLS et en texte clair sont toutes deux acceptées, ce qui signifie que le mesh fournit une attestation d'identité uniquement pour les connexions qui présentent volontairement un certificat. Un adversaire opérant depuis un pod non maillé — un init container compromis, un pod de débogage accidentellement laissé en cours d'exécution, une charge de travail DaemonSet qui n'a jamais été injectée avec un sidecar — peut communiquer avec n'importe quel service en texte clair, contournant entièrement la vérification d'identité. Fixez une date limite ferme pour le mode STRICT et utilisez istioctl analyze pour énumérer les chemins en texte clair restants avant cette date.

Observabilité sans exfiltration de données : métriques et traçage en cluster

Un service mesh génère automatiquement une télémétrie riche depuis ses proxies sidecar : taux de requêtes par service, taux d'erreurs ventilés par code d'état HTTP et statut gRPC, percentiles de latence (p50, p95, p99), nombres de connexions actives et métriques de handshake TLS. Dans un déploiement cloud commercial, cette télémétrie est généralement transférée vers une plateforme d'observabilité SaaS. Dans un cluster militaire classifié, tout pipeline de télémétrie envoyant des données en dehors de la limite de classification est un vecteur d'exfiltration potentiel et est architecturalement interdit. L'ensemble de la pile d'observabilité doit être déployé à l'intérieur de la limite du cluster et doit lui-même être contrôlé par les mêmes politiques de mesh qui régissent le trafic applicatif.

La pile d'observabilité standard en cluster pour un service mesh se compose de Prometheus pour la collecte de métriques, Grafana pour la visualisation, et Jaeger ou Tempo pour le traçage distribué. Prometheus collecte le point de terminaison des statistiques Envoy (port 15090) ou le point de terminaison de métriques linkerd-proxy sur chaque pod maillé à un intervalle configurable. Grafana se connecte exclusivement aux instances Prometheus et Loki en cluster — aucune connexion à des sources de données externes n'est configurée. Jaeger reçoit les spans de trace transmis par le sidecar Envoy via le protocole Zipkin ou OpenTelemetry vers un point de terminaison de collecteur local au cluster. Tout le stockage persistant des métriques, des traces et des journaux utilise des PersistentVolumes locaux au cluster adossés à un stockage de blocs chiffré. L'espace de noms de surveillance lui-même porte une NetworkPolicy qui bloque tout trafic sortant vers des plages d'IP externes, rendant architecturalement impossible la sortie de la télémétrie du cluster même si un pipeline mal configuré était introduit.

Pour les clusters Kubernetes renforcés pour les charges de travail de défense, il convient de noter que la pile d'observabilité doit également être approvisionnée depuis des registres air-gappés. Les images Prometheus, Grafana, Jaeger et Loki doivent être répliquées dans le registre interne avec des condensés vérifiés avant que le cluster ne soit placé derrière la limite de classification. Les politiques d'extraction d'images doivent être définies sur Never ou IfNotPresent en sachant que les images ne seront jamais actualisées depuis une source externe. Toute mise à jour de la pile d'observabilité nécessite un processus formel de gestion des changements qui fait passer les images mises à jour par la procédure air-gap plutôt qu'une simple mise à niveau de chart Helm contre un dépôt de charts public.

Surcharge des sidecars dans les clusters edge de défense contraints en ressources

Les clusters edge déployés à proximité des opérations — fonctionnant sur des serveurs à petit facteur de forme ou des plateformes de calcul militarisées avec 32 à 64 Go de RAM et 4 à 8 nœuds — font face à un budget de ressources qui fait de la surcharge des sidecars une contrainte d'ingénierie réelle plutôt qu'une préoccupation théorique. Un sidecar Envoy Istio en régime permanent consomme 50 à 100 Mo de taille de jeu résident et jusqu'à 0,5 vCPU pendant les périodes à fort débit. Un cluster exécutant 40 pods consomme 2 à 4 Go de mémoire sidecar agrégée, soit environ 6 à 12 % de la RAM totale d'un cluster de 32 Go. Le plan de contrôle lui-même — istiod, Prometheus, Grafana, Jaeger — ajoute encore 2 à 4 Go, portant la surcharge totale de l'infrastructure mesh à 15 à 25 % de la mémoire du cluster avant que les charges de travail applicatives ne soient prises en compte.

Trois options réduisent cette surcharge dans les déploiements contraints. Premièrement, le proxy Rust de Linkerd est le sidecar le plus efficace disponible : 10 à 20 Mo par pod plutôt que 50 à 100 Mo pour Envoy, et une surcharge de latence inférieure à 1 ms par saut. Pour les clusters dont les exigences de granularité de politique L7 peuvent être satisfaites par le modèle de politique de Linkerd, les économies de mémoire sont substantielles. Deuxièmement, le mode ambient mesh d'Istio (disponible à partir d'Istio 1.22) élimine entièrement les sidecars par pod, les remplaçant par un proxy ztunnel par nœud qui gère le mTLS pour tous les pods sur le nœud. Le mode ambient réduit la surcharge par pod à quasi zéro au prix de déplacer l'application des politiques des sidecars par charge de travail aux proxies par nœud, ce qui offre une granularité de politique légèrement moins fine pour les charges de travail nécessitant des décisions d'autorisation par requête. Troisièmement, l'injection sélective — injecter des sidecars uniquement dans les pods nécessitant une application des politiques L7, et utiliser le chiffrement L4 basé sur eBPF de Cilium pour le reste — équilibre la granularité d'application et la consommation de ressources pour les charges de travail de cluster hétérogènes.

L'interaction entre la consommation de ressources des sidecars et la gestion des secrets dans les pipelines CI/CD de défense mérite d'être notée explicitement. Les sidecars d'injection de secrets (Vault Agent Injector, Secrets Store CSI Driver) ajoutent un autre conteneur par pod. Un cluster edge qui exécute à la fois un sidecar mesh et un sidecar d'injection de secrets par pod d'application a deux conteneurs d'infrastructure pour chaque conteneur d'application, doublant le nombre de conteneurs et ajoutant 60 à 120 Mo de surcharge d'infrastructure par paire de pods. La consolidation est possible : l'agent SPIRE peut servir à la fois d'émetteur d'identité de mesh et de mécanisme de livraison de secrets de charge de travail pour les secrets pouvant être exprimés comme des rôles Vault autorisés par SVID, éliminant le sidecar d'injection de secrets séparé pour ces charges de travail.

Intégration de la politique de service mesh avec RBAC et la gestion des secrets

Kubernetes RBAC régit qui peut lire et modifier les objets de l'API Kubernetes — y compris les ressources AuthorizationPolicy, PeerAuthentication et de configuration du mesh qui définissent la posture de sécurité du service mesh. Si la configuration RBAC autorise un large ensemble de principals à modifier les objets AuthorizationPolicy, la couche de contrôle d'accès du mesh peut être affaiblie par n'importe lequel de ces principals. Un déploiement de défense correct traite les manifestes de politique de mesh comme des objets de sécurité à haute valeur : seul le compte de service CI/CD qui applique les manifestes depuis le dépôt de politiques versionné devrait avoir un accès en écriture aux ressources AuthorizationPolicy et PeerAuthentication, et seuls les administrateurs du cluster devraient pouvoir modifier les entrées d'enregistrement SPIRE. Tous les autres principals — y compris les comptes de service d'applications individuelles — devraient avoir un accès en lecture seule ou aucun accès à ces objets.

La relation entre la couche d'identité du mesh et la couche de gestion des secrets est bidirectionnelle. Le mesh utilise les SVID SPIFFE pour authentifier les appels service à service au niveau de la couche de transport. La gestion des secrets (Vault, Kubernetes Secrets Store CSI Driver) utilise ces mêmes identités basées sur SVID pour déterminer quelles charges de travail peuvent recevoir quels secrets au niveau de la couche applicative. Une charge de travail avec SPIFFE ID spiffe://cluster.local/ns/fusion/sa/data-processor peut être mappée à un rôle Vault accordant un accès en lecture exactement aux identifiants de base de données dont ce service a besoin — et rien d'autre. Cela signifie que le système d'identité de mesh et le système de livraison de secrets partagent une seule source faisant autorité de l'identité de charge de travail, éliminant le risque d'une inadéquation où une charge de travail bénéficie d'un accès réseau mais pas des secrets nécessaires pour l'utiliser, ou vice versa. Le maintien de cet alignement exige que les entrées d'enregistrement SPIRE, les définitions de rôle Vault et les manifestes AuthorizationPolicy du mesh soient tous mis à jour ensemble lors de l'ajout, la modification ou la décommission d'un service.

La journalisation d'audit relie les trois systèmes pour la conformité et la réponse aux incidents. Le sidecar de mesh consigne chaque décision d'accès — autorisation ou refus — avec le SVID source vérifié, la destination, l'opération et l'horodatage. Vault consigne chaque accès aux secrets avec l'identité demandante et le chemin du secret accédé. Les journaux d'audit du serveur d'API Kubernetes enregistrent chaque appel d'API régi par RBAC. Ensemble, ces trois flux de journaux fournissent une piste d'audit complète de « quel appel réseau a été effectué » à « quels secrets ont été accédés en conséquence » jusqu'à « qui a modifié la politique qui régissait les deux ». Pour les environnements de défense opérant sous des exigences formelles d'accréditation, cette traçabilité à travers les couches d'identité, de contrôle d'accès et de secrets est souvent une exigence de conformité non négociable plutôt qu'une commodité opérationnelle.

Sécurité zero-trust service à service pour les environnements classifiés

Corvus QUANTUM est construit sur des principes zero-trust avec mTLS mutuel sur toutes les communications service à service, politique de trafic appliquée et observabilité en cluster répondant aux exigences des environnements militaires classifiés.

Découvrir Corvus QUANTUM → Demander un briefing

Cette analyse a été préparée par les ingénieurs de Corvus Intelligence qui développent des applications ISR et de terrain critiques pour les organisations de défense et gouvernementales. En savoir plus sur notre équipe →