BeyondProd

Ce contenu a été mis à jour pour la dernière fois en septembre 2023, et correspond à l'état des connaissances à sa date de rédaction. Les règles et les systèmes de sécurité Google peuvent changer par la suite, car nous améliorons continuellement la protection de nos clients.

Ce document explique comment Google met en œuvre la sécurité dans notre infrastructure à l'aide d'une architecture cloud native appelée BeyondProd. BeyondProd fait référence aux services et aux contrôles de notre infrastructure qui fonctionnent ensemble pour protéger les charges de travail. Les charges de travail sont les tâches uniques réalisées par une application. BeyondProd permet de protéger les microservices que nous exécutons dans notre environnement, y compris la façon dont nous modifions le code et dont nous accédons aux informations sur les utilisateurs.

Ce document fait partie d'une série d'articles techniques décrivant les technologies, telles que BeyondCorp Enterprise , que nous avons développé pour protéger les plates-formes Google contre les menaces sophistiquées. BeyondCorp Enterprise met en œuvre une architecture zéro confiance conçue pour fournir un accès sécurisé aux plates-formes Google et aux services qui y sont exécutés. Comme BeyondCorp Enterprise, BeyondProd ne s'appuie pas sur les protections traditionnelles du périmètre réseau, telles que les pare-feu. Au lieu de cela, BeyondProd permet de créer une relation de confiance entre les microservices en utilisant des caractéristiques telles que la provenance du code, les identités de service et le matériel de confiance. Cette confiance s'étend aux logiciels exécutés dans Google Cloud et aux logiciels déployés et accessibles par les clients Google Cloud.

Ce document décrit les avantages de BeyondProd, ses services et ses processus, ainsi que la manière dont nous avons migré vers cette architecture. Pour en savoir plus sur la sécurité de notre infrastructure, consultez la Présentation de la sécurité sur l'infrastructure de Google.

Introduction

Les architectures de sécurité modernes ont abandonnée le modèle de sécurité périmétrique traditionnel dans lequel un pare-feu protège le périmètre et où tous les utilisateurs ou services du périmètre sont considérés comme approuvés.

Aujourd'hui, les utilisateurs sont mobiles et opèrent généralement en dehors du périmètre de sécurité traditionnel d'une organisation, par exemple depuis leur domicile, installés dans un café ou à bord d'un avion. Avec BeyondCorp Enterprise, nous accordons l'accès aux ressources de l'entreprise en utilisant plusieurs facteurs, tels que l'identité de l'utilisateur, l'identité de l'appareil utilisé pour accéder à la ressource, l'état de l'appareil et des signaux de confiance, tels que les comportements des utilisateurs et les listes de contrôle d'accès.

BeyondProd gère pour les services de production la même préoccupation que BeyondCorp Enterprise gère pour les utilisateurs. Dans une architecture cloud native, nous ne pouvons pas nous contenter d'un pare-feu pour protéger le réseau de production. Les microservices se déplacent et sont déployés dans différents environnements, sur des hôtes hétérogènes, et fonctionnent à différents niveaux de confiance et de sensibilité. Dans BeyondCorp Enterprise, la confiance des utilisateurs dépend de caractéristiques telles que l'état contextuel des appareils plutôt que de la possibilité de se connecter au réseau d'entreprise. De la même façon, dans BeyondProd, la confiance accordée à un service doit dépendre de caractéristiques telles que la provenance du code, le matériel approuvé et l'identité du service, plutôt que de son emplacement dans le réseau de production (adresse IP ou nom d'hôte, par exemple).

Infrastructure conteneurisée

Notre infrastructure déploie les charges de travail sous forme de microservices individuels dans des conteneurs. Les microservices séparent les tâches individuelles d'une application en différents services. Chaque service peut être développé et géré indépendamment avec ses propres API, déploiement, scaling et gestion des quotas. Les microservices sont indépendants, modulaires, dynamiques et éphémères. Ils peuvent être répartis sur de nombreux hôtes, clusters ou même dans le cloud. Dans une architecture de microservices, une charge de travail peut correspondre à un ou plusieurs microservices.

Une infrastructure conteneurisée signifie que chaque microservice est déployé sous la forme d'un ensemble unique de conteneurs mobiles et planifiables. Pour gérer ces conteneurs en interne, nous avons développé un système d'orchestration de conteneurs appelé Borg , qui déploie plusieurs milliards de conteneurs par semaine Borg est le système de gestion de conteneurs unifié de Google et s'inspire de Kubernetes.

Les conteneurs facilitent et optimisent la planification des charges de travail sur les machines. La conteneurisation de microservices permet de diviser les charges de travail en unités plus petites et plus faciles à gérer pour la maintenance et la découverte. Cette architecture adapte les charges de travail selon les besoins : en cas de forte demande pour une charge de travail spécifique, plusieurs machines exécutent des copies du même conteneur afin de répondre à l'ampleur de la charge de travail requise.

Chez Google, la sécurité joue un rôle essentiel à chaque évolution de notre architecture. Avec cette architecture de microservices et ce processus de développement, notre objectif est de résoudre les problèmes de sécurité le plus tôt possible dans le cycle de développement et de déploiement (lorsque la résolution des problèmes est moins coûteuse), et de façon uniforme et cohérente. Cela permet ainsi aux développeurs de passer moins de temps sur des tâches de sécurité tout en obtenant des résultats plus sécurisés.

Avantages de BeyondProd

BeyondProd offre à l'infrastructure Google de nombreux avantages en matière d'automatisation et de sécurité. Les avantages sont les suivants :

  • Protection de la périphérie du réseau : les charges de travail sont isolées des attaques réseau et du trafic non autorisé provenant d'Internet. Bien qu'une approche périmétrique ne soit pas un nouveau concept, elle reste une bonne pratique de sécurité pour les architectures cloud. Une approche périmétrique protège autant d'infrastructures que possible contre le trafic non autorisé et les attaques potentielles sur Internet (attaques de déni de service basées sur le volume, par exemple).
  • Pas de confiance mutuelle inhérente entre les services : seuls les appelants ou les services authentifiés, approuvés et autorisés peuvent accéder à tout autre service. Cela empêche les pirates informatiques d'utiliser du code non approuvé pour accéder à un service. Si un service est compromis, cet avantage empêche le pirate d'effectuer des actions qui lui permettraient d'élargir son emprise. Cette absence de confiance mutuelle, associée à un contrôle d'accès précis, permet de limiter le rayon d'action d'un piratage.
  • Machines fiables qui exécutent du code de provenance connue : les identités de service sont obligées d'utiliser uniquement du code et des configurations autorisés, et sont exclusivement exécutées dans des environnements autorisés et vérifiés.
  • Application cohérente des règles entre les différents services : l'application cohérente des règles permet de s'assurer que les décisions d'accès sont fiables pour l'ensemble des services. Par exemple, vous pouvez créer une application de règle qui vérifie les requêtes d'accès aux informations sur les utilisateurs. Pour accéder au service, un utilisateur final autorisé doit présenter une requête validée, et un administrateur doit fournir une justification professionnelle.
  • Déploiement de modifications simple, automatisé et standardisé : il est facile de contrôler l'impact sur la sécurité des éventuelles modifications apportées à l'infrastructure et de déployer les correctifs de sécurité en minimisant l'impact sur la production.
  • Isolement entre les charges de travail partageant un système d'exploitation : si un service est compromis, il ne peut pas affecter la sécurité d'une autre charge de travail exécutée sur le même hôte. Cela limite le rayon d'action d'un piratage potentiel.
  • Matériel de confiance et attestation : une racine de confiance matérielle permet de garantir que seul du code connu et autorisé (du micrologiciel au mode utilisateur) s'exécute sur l'hôte, avant que des charges de travail ne soient programmées pour être exécutées sur l'hôte.

Cela signifie que les conteneurs et les microservices exécutés dans notre architecture cloud peuvent être déployés, communiquer les uns avec les autres et fonctionner côte à côte sans affaiblir la sécurité de notre infrastructure. De plus, les développeurs de microservices individuels ne sont pas encombrés par les détails de sécurité et de mise en œuvre de l'infrastructure sous-jacente.

Services de sécurité BeyondProd

Nous avons conçu et développé plusieurs services de sécurité BeyondProd pour créer les avantages décrits dans la section Avantages de BeyondProd. Les sections suivantes décrivent ces services de sécurité.

Google Front End pour la protection du réseau en périphérie

Google Front End (GFE) fournit une protection de la périphérie des réseaux. GFE termine la connexion de l'utilisateur final et fournit un point central pour appliquer les bonnes pratiques TLS.

Bien que nous ne privilégions plus la sécurité périmétrique, GFE constitue toujours un élément important de notre stratégie de protection des services internes contre les attaques par déni de service. GFE est le premier point d'entrée pour un utilisateur se connectant à l'infrastructure Google. Une fois qu'un utilisateur se connecte à notre infrastructure, GFE est également chargé de l'équilibrage des charges et de la redirection du trafic entre les régions, si nécessaire. GFE est le proxy de périphérie qui dirige le trafic vers le microservice adéquat.

Les VM clientes sur Google Cloud ne s'enregistrent pas auprès de GFE. À la place, elles s'enregistrent auprès de Cloud Front End, une configuration spéciale de GFE qui utilise la pile réseau de Compute Engine. Cloud Front End permet aux VM clientes d'accéder directement à un service Google à l'aide de leur adresse IP publique ou privée. (Les adresses IP privées ne sont disponibles que lorsque l'accès privé à Google est activé.)

Application Layer Transport Security pour l'approbation entre les services

Application Layer Transport Security (ALTS) permet de garantir l'absence de confiance mutuelle inhérente entre les services. ALTS est utilisé pour l'authentification des appels de procédure à distance (RPC) ainsi que pour l'intégrité, le chiffrement du trafic et les identités de service. ALTS est un système d'authentification mutuelle et de chiffrement des données en transit pour les services de l'infrastructure Google. En général, les identités sont liées à des services plutôt qu'à un nom de serveur ou à un hôte spécifique. Cette liaison permet une réplication transparente des microservices, un équilibrage de charge et une replanification entre les hôtes.

Chaque machine dispose d'un identifiant ALTS provisionné à l'aide du système d'intégrité de l'hôte, qui ne peut être déchiffré que si le système d'intégrité de l'hôte a vérifié que le démarrage sécurisé a réussi. La plupart des services Google fonctionnent comme des microservices exécutés au-dessus de Borg, et ces microservices possèdent chacun leur propre identité ALTS. Borg Prime , le contrôleur centralisé de Borg, attribue ces identifiants de microservice ALTS aux charges de travail en fonction de l'identité du microservice. Les identifiants ALTS au niveau machine constituent le canal sécurisé pour le provisionnement des identifiants de microservice, de sorte que seules les machines ayant réussi le processus de démarrage validé d'intégrité de l'hôte peuvent héberger des charges de travail. Pour en savoir plus sur les identifiants ALTS, consultez la section Certificats de charge de travail.

Autorisation binaire pour Borg pour la provenance du code

L'autorisation binaire pour Borg (BAB) fournit une vérification de la provenance du code. L'autorisation binaire pour Borg est une vérification d'application forcée lors du déploiement, qui permet de s'assurer que le code répond aux exigences de sécurité interne avant son déploiement. Par exemple, le contrôle de l'application de l'autorisation binaire pour Borg garantit que les modifications sont examinées par un deuxième ingénieur avant que le code ne soit envoyé vers notre dépôt de code source et que les binaires ne soient compilés de manière vérifiable sur une infrastructure dédiée. Dans notre infrastructure, l'autorisation binaire pour Borg limite le déploiement de microservices non autorisés.

Intégrité de l'hôte pour l'approbation de la machine

L'intégrité de l'hôte vérifie l'intégrité du logiciel système hôte via un processus de démarrage sécurisé et est protégée par une puce de sécurité de racine de confiance matérielle (appelée Titan) lorsqu'elle est compatible. Les vérifications de l'intégrité de l'hôte incluent la vérification des signatures numériques sur le BIOS, le contrôleur de gestion de baseboard (BMC) le bootloader et le noyau OS. Lorsque cela est possible, les vérifications de l'intégrité de l'hôte peuvent inclure du code en mode utilisateur et des micrologiciels de périphériques (cartes d'interface réseau, par exemple). En plus de la validation de la signature numérique, l'intégrité de l'hôte permet de s'assurer que chaque hôte exécute la version prévue de ces composants logiciels.

Gestion des accès aux services et demandes de contexte d'utilisateur final pour l'application des règles

La gestion des accès aux services et les demandes de contexte d'utilisateur final permettent de garantir l'application cohérente des règles dans les différents services.

La gestion des accès aux services limite la façon dont les données sont accessibles entre les services. Lorsqu'un RPC est envoyé d'un service à un autre, la gestion des accès aux services définit les règles d'autorisation et d'audit dont les services ont besoin pour accéder aux données du service destinataire. Cela limite la façon dont les données sont accessibles, accorde le niveau minimal d'accès requis et indique comment cet accès peut être contrôlé. Dans l'infrastructure Google, la gestion des accès aux services limite l'accès d'un microservice aux données d'un autre microservice et permet des analyses globales des contrôles d'accès.

Les demandes de contexte d'utilisateur final sont émises par un service d'authentification d'utilisateur final et fournissent aux services une identité d'utilisateur distincte de leur identité de service. Ces demandes sont des identifiants transmissibles, émis au niveau central, dont l'intégrité est protégée et qui attestent de l'identité d'un utilisateur final qui a demandé le service. Ces demandes réduisent le besoin de confiance entre les services car les identités de pair utilisant ALTS peuvent être insuffisantes pour accorder un accès lorsque de telles décisions d'accès sont, généralement, également basées sur l'identité de l'utilisateur final.

Outils Borg pour le déploiement automatique des modifications et l'évolutivité

Les outils Borg pour déploiements bleu-vert fournissent un déploiement simple, automatisé et standardisé des modifications. Un déploiement bleu-vert permet de déployer une modification d'une charge de travail sans affecter le trafic entrant, de sorte que l'utilisateur final ne remarque aucun temps d'arrêt en accédant à l'application.

Un job Borg est une instance unique d'un microservice qui exécute une partie d'une application. Les jobs évoluent de manière à pouvoir gérer la charge, en déployant de nouveaux jobs lorsque la charge augmente et en supprimant des jobs existants lorsque la charge diminue.

Les outils Borg sont chargés de migrer les charges de travail en cours d'exécution lorsque nous effectuons des tâches de maintenance. Lorsqu'un nouveau job Borg est déployé, un équilibreur de charge déplace progressivement le trafic d'un job existant vers le nouveau. Cela permet de mettre à jour un microservice sans temps d'arrêt et sans que l'utilisateur ne s'en aperçoive.

Cet outil nous permet également d'appliquer des mises à niveau lorsque nous ajoutons de nouvelles fonctionnalités et d'appliquer des mises à jour de sécurité critiques sans temps d'arrêt (par exemple, Heartbleed et Spectre/Meltdown). Pour les modifications qui affectent notre infrastructure, nous utilisons la migration à chaud des VM clientes pour nous assurer que les charges de travail ne sont pas affectées.

Pour en savoir plus, consultez la section Autorisation binaire pour Borg.

Noyau gVisor pour l'isolation de charge de travail

Le noyau gVisor permet d'isoler les charges de travail qui partagent un système d'exploitation. gVisor utilise un noyau d'espace utilisateur pour intercepter et gérer les appels système, réduisant ainsi l'interaction avec l'hôte et la surface d'attaque potentielle. Ce noyau fournit la plupart des fonctionnalités requises pour exécuter une application et limite la surface du noyau hôte accessible à l'application. gVisor est l'un des outils que nous utilisons pour isoler les charges de travail internes et les charges de travail des clients Google Cloud qui s'exécutent sur un même hôte. Pour en savoir plus sur les autres outils d'isolation, consultez la page Isolation de code.

Protéger les informations sur les utilisateurs avec BeyondProd

Cette section décrit comment les services BeyondProd fonctionnent ensemble pour protéger les informations sur l'utilisateur dans notre infrastructure. Les sections ci-dessous décrivent deux exemples :

  • Accès aux demandes de renseignements sur un utilisateur, depuis leur création jusqu'à leur livraison à la destination.
  • Modification du code pour passer du développement à la production.

Toutes les technologies répertoriées ne sont pas utilisées dans toutes les parties de notre infrastructure. Cela dépend des services et des charges de travail.

Accès aux données des utilisateurs

Le schéma ci-dessous illustre le processus utilisé par notre infrastructure pour vérifier qu'un utilisateur est autorisé à accéder aux informations sur les utilisateurs.

Contrôles de sécurité cloud natifs de Google pour l'accès aux informations sur les utilisateurs

La procédure pour accéder aux comptes utilisateur est la suivante :

  1. Un utilisateur envoie une requête à GFE.
  2. GFE termine la connexion TLS et transfère la requête à l'interface du service approprié à l'aide d'ALTS.
  3. L'interface de l'application authentifie la demande de l'utilisateur via un service central d'authentification de l'utilisateur final (EUA) et, en cas de réussite, reçoit une demande de contexte d'utilisateur final cryptographique de courte durée.
  4. L'interface de l'application effectue un RPC via ALTS vers un service de backend de stockage, en transférant la demande dans la requête de backend.
  5. Le service de backend s'assure que les critères suivants sont satisfaits en utilisant la gestion des accès aux services :
    • L'interface est authentifiée à l'aide d'un certificat valide et non révoqué. Cette vérification implique l'exécution sur un hôte de confiance et la réussite des vérifications d'autorisation binaire pour Borg.
    • L'identité ALTS du service d'interface est autorisée à envoyer des requêtes au service de backend et à présenter une demande EUC.
    • La demande de contexte d'utilisateur final est valide.
    • L'utilisateur de la demande EUC est autorisé à accéder aux données demandées.

Si l'une de ces vérifications échoue, la demande est refusée.

Si ces vérifications réussissent, les données sont renvoyées à l'interface de l'application autorisée et transmises à l'utilisateur autorisé.

Dans la plupart des cas, une chaîne d'appels backend est établie et chaque service intermédiaire effectue une vérification d'accès au service sur les appels RPC entrants, et la demande est transférée sur les appels RPC sortants.

Pour en savoir plus sur le routage du trafic au sein de notre infrastructure, consultez la page Routage du trafic.

Modifier du code

Le schéma ci-dessous montre comment une modification de code est déployée.

Processus de modification de code

Les étapes pour modifier du code sont les suivantes :

  1. Un développeur modifie un microservice protégé par l'autorisation binaire pour Borg. La modification est envoyée à notre dépôt de code central, , qui applique un examen du code. Après approbation, la modification est envoyée au système de compilation de confiance, , qui produit un package avec un certificat manifeste de compilation vérifiable et signé.

  2. Au moment du déploiement, l'autorisation binaire pour Borg vérifie que ce processus a été suivi par la validation du certificat signé à partir du pipeline de compilation.

  3. Borg gère toutes les mises à jour des charges de travail à l'aide d'un modèle de fiabilité qui garantit une interruption minimale des services, qu'il s'agisse d'un déploiement de routine ou d'un correctif de sécurité d'urgence.

  4. GFE transfère le trafic vers le nouveau déploiement via l'équilibrage de charge afin d'assurer la continuité des opérations.

Pour en savoir plus sur ce processus, consultez la page Notre processus de développement et de production.

Toutes les charges de travail nécessitent une isolation. Si la charge de travail est moins fiable car le code source provient de l'extérieur de Google, elle peut être déployée dans un environnement protégé gVisor ou utiliser d'autres couches d'isolation. Cette isolation permet de contenir une personne mal intentionnée qui parvient à compromettre une application.

Implications de la sécurité cloud native

Les sections suivantes comparent les aspects de sécurité d'infrastructure traditionnelle à leurs équivalents dans une architecture cloud native.

Architecture de l'application

Un modèle de sécurité plus traditionnel, axé sur la sécurité périmétrique, ne peut pas protéger seul une architecture cloud native. Traditionnellement, les applications monolithiques utilisaient une architecture à trois niveaux et étaient déployées dans des centres de données privés disposant de suffisamment de capacité pour gérer la charge maximale des événements critiques. Les applications présentant des exigences spécifiques en termes de matériel ou de réseau sont volontairement déployées sur des machines spécifiques qui, en général, disposent d'adresses IP fixes. Les déploiements étaient peu fréquents, volumineux et difficiles à coordonner, car les modifications qui en résultent affectaient simultanément de nombreuses parties de l'application. Cela conduit à des applications très durables qui sont mises à jour moins fréquemment et pour lesquelles les correctifs de sécurité sont généralement appliqués de manière moins fréquente.

Toutefois, dans un modèle cloud natif, les applications doivent être portables entre différents environnements, car elles peuvent s'exécuter dans des clouds publics, des centres de données privés ou des services hébergés par des tiers. Par conséquent, au lieu d'une application monolithique, une application conteneurisée et divisée en microservices devient une solution idéale pour les environnements cloud. Les conteneurs dissocient les binaires dont votre application a besoin du système d'exploitation hôte sous-jacent et rendent les applications plus portables. Nos conteneurs sont immuables, ce qui signifie qu'une fois déployés, ils ne changent pas. Au lieu de cela, ils sont fréquemment reconstruits et redéployés.

Les conteneurs étant redémarrés, arrêtés ou reprogrammés fréquemment, la réutilisation et le partage du matériel et des réseaux sont plus fréquents. Avec un processus de conception et de distribution standard, le processus de développement est plus homogène et uniforme entre les équipes, même si elles gèrent indépendamment le développement de leurs microservices. Par conséquent, les considérations de sécurité (telles que les examens de sécurité, l'analyse du code et la gestion des failles) peuvent être abordées au début des cycles de développement.

Maillage de services

En créant une infrastructure partagée et sécurisée que tous les développeurs utilisent, la charge imposée aux développeurs pour la mise en œuvre des exigences de sécurité courantes est réduite. Les fonctionnalités de sécurité ne doivent nécessiter aucune intégration ou presque dans chaque application, et être plutôt fournies sous la forme d'une structure enveloppant et connectant tous les microservices. C'est ce que l'on appelle généralement un maillage de services. Cela signifie également que la sécurité peut être gérée et mise en œuvre indépendamment des activités de développement ou de déploiement habituelles.

Un maillage de services est une structure partagée au niveau de la couche d'infrastructure qui enveloppe et connecte tous les microservices. Un maillage de services permet une communication de service à service, qui peut contrôler le trafic, appliquer des règles et surveiller les appels de service de manière centralisée.

Sécurité "zéro confiance"

Dans un modèle de sécurité traditionnel qui utilise des centres de données privés, les applications d'une organisation dépendent d'un pare-feu pour protéger les charges de travail contre les menaces réseau externes.

Avec un modèle de sécurité "zéro confiance", il n'y a pas de pare-feu. Au lieu de cela, d'autres contrôles, tels que l'identité, l'authentification et l'autorisation de la charge de travail, permettent de protéger les microservices en s'assurant que les connexions internes ou externes sont validées avant d'être en mesure de réaliser une transaction. Lorsque vous supprimez votre dépendance aux pare-feu ou aux contrôles basés sur le réseau, vous pouvez mettre en œuvre la segmentation au niveau du microservice, sans confiance inhérente entre les services. Avec la segmentation au niveau du microservice, le trafic peut avoir différents niveaux de confiance et différents contrôles, ce qui signifie que vous n'êtes plus restreint à la seule différenciation entre trafic interne et trafic externe.

Exigences de sécurité partagées intégrées dans des piles de service

Dans un modèle de sécurité traditionnel, les applications individuelles sont chacune responsables de leurs propres exigences de sécurité, indépendamment des autres services. Ces exigences incluent la gestion des identités, la terminaison TLS et la gestion des accès aux données. Cela peut entraîner des mises en œuvre incohérentes ou des problèmes de sécurité non résolus, car les problèmes doivent être résolus en de nombreux endroits, ce qui rend les correctifs plus difficiles à appliquer.

Dans une architecture cloud native, les composants sont beaucoup plus souvent réutilisés entre les services. Les goulots d'étranglement permettent d'appliquer les règles de manière cohérente à l'ensemble des services. Il est possible d'appliquer différentes règles à l'aide de différents services de sécurité. Plutôt que d'exiger que chaque application mette en œuvre de façon distincte les services de sécurité critiques, vous pouvez séparer les différentes règles en des microservices distincts. Par exemple, vous pouvez créer une règle pour garantir un accès autorisé aux données utilisateur et une autre pour assurer l'utilisation de suites de chiffrement TLS à jour.

Processus standardisés avec des déploiements plus fréquents

Dans un modèle de sécurité traditionnel, les services partagés sont limités et le code est souvent dupliqué et couplé dans le cadre du développement local. Le partage limité rend plus difficile la détermination de l'impact d'une modification et de l'effet de cette modification sur de nombreuses parties d'une application. Par conséquent, les déploiements sont peu fréquents et difficiles à coordonner. Pour apporter une modification, les développeurs peuvent être amenés à mettre à jour chaque composant directement (par exemple, en ouvrant des connexions SSH sur chaque machine virtuelle pour mettre à jour une configuration). Dans l'ensemble, cela peut entraîner des applications très durables.

Du point de vue de la sécurité, lorsqu'un code est souvent dupliqué, il est plus difficile de le vérifier et surtout, lors de la correction d'une faille, de s'assurer que celle-ci est corrigée partout.

Dans une architecture cloud native, les déploiements sont fréquents et standardisés. Ce processus permet de décaler la sécurité vers la gauche dans le cycle de vie du développement logiciel. L'expression "décaler vers la gauche" revient à intégrer ces étapes plus tôt dans le cycle de vie du développement logiciel, qui peut inclure des étapes telles que le codage, la compilation, les tests, la validation et le déploiement. Le décalage vers la gauche permet une application plus simple et plus cohérente de la sécurité, ce qui inclut l'application régulière de correctifs de sécurité.

Transitionner vers BeyondProd

La transition de Google vers BeyondProd a nécessité des changements dans deux domaines principaux : notre infrastructure et notre processus de développement. Nous avons abordé ces changements simultanément, mais vous pouvez les gérer indépendamment si vous souhaitez configurer quelque chose de similaire dans votre environnement.

Modification de notre infrastructure

Notre objectif est d'automatiser la sécurité sur l'ensemble de notre infrastructure, car nous pensons que la sécurité doit évoluer de la même manière que les services. Les services doivent être sécurisés par défaut plutôt que d'être non sécurisés par exception. Une intervention humaine directe sur notre infrastructure doit être l'exception plutôt que la règle, et les interventions doivent être auditables lorsqu'elles se produisent. Nous pouvons ensuite authentifier un service en fonction du code et de la configuration déployés pour le service, plutôt qu'en fonction des personnes ayant déployé le service.

Nous avons commencé par créer une base solide d'identité, d'authentification et d'autorisation des services. Un microservice utilise une identité de service pour s'authentifier auprès des autres services exécutés dans l'infrastructure. Le fait de disposer d'identités de service fiables nous a permis de mettre en œuvre des fonctionnalités de sécurité de niveau supérieur en validant ces identités de service, par exemple avec la gestion des accès aux services et les demandes de contexte d'utilisateur final. Pour faciliter la transition des nouveaux services et des services existants, ALTS a d'abord été fourni sous la forme d'une bibliothèque avec un seul daemon d'assistance. Ce daemon a été exécuté sur l'hôte appelé par chaque service et a évolué au fil du temps dans une bibliothèque utilisant les identifiants de service. La bibliothèque ALTS a été intégrée de manière transparente dans la bibliothèque RPC principale. Cette intégration a facilité l'adoption à grande échelle, sans créer de contraintes excessives pour les équipes de développement individuelles. Le déploiement d'ALTS était une condition préalable au déploiement de la gestion des accès aux services et des demandes de contexte d'utilisateur final.

Modification de nos processus de développement

Pour Google, il était essentiel de mettre en place un processus robuste de compilation et d'examen du code afin de garantir l'intégrité des services exécutés. Nous avons donc créé un processus de compilation centralisé qui nous a permis de commencer à appliquer les conditions nécessaires, telles qu'un examen du code par deux personnes et des tests automatisés au moment de la compilation et du déploiement. Pour plus d'informations sur le déploiement, consultez la section Autorisation binaire pour Borg.

Une fois les principes de base en place, nous avons commencé à répondre au besoin d'exécuter un code externe non approuvé dans nos environnements. Pour atteindre cet objectif, nous avons commencé l'isolation, d'abord avec ptrace, puis plus tard avec gVisor. De même, les déploiements bleu-vert ont offert des avantages significatifs en termes de sécurité (pour l'application des correctifs, par exemple) et de fiabilité.

Nous avons rapidement constaté qu'il était plus facile qu'un service démarre par la journalisation des cas de non-respect des règles plutôt que par leur blocage. Cette approche offrait deux avantages :

  • Tout d'abord, elle a permis aux propriétaires de services de tester la modification et d'évaluer l'impact éventuel de l'adoption d'un environnement cloud natif sur leur service.
  • De plus, elle nous a permis de corriger les éventuels bugs et d'identifier les fonctionnalités supplémentaires que nous devrions éventuellement fournir aux équipes de service.

Par exemple, lorsqu'un service est intégré à l'autorisation binaire pour Borg, les propriétaires de service activent le mode audit uniquement. Cela leur permet d'identifier le code ou les workflows qui ne répondent pas à leurs besoins. Après avoir résolu les problèmes signalés par le mode audit uniquement, les propriétaires de services passent en mode d'application. Dans gVisor, nous avons effectué cela en isolant d'abord les charges de travail, malgré des écarts de compatibilité dans les fonctionnalités d'isolation, puis en comblant systématiquement ces écarts pour améliorer l'isolation.

Étapes suivantes