Créer et personnaliser des charges de travail


Une charge de travail est créée par un auteur de charge de travail et traite les données confidentielles avec lesquelles les collaborateurs de données souhaitent travailler.

Pour créer une charge de travail, un auteur doit rassembler les ressources suivantes:

  • Une application pour traiter les données confidentielles. Vous pouvez écrire votre application dans la langue de votre choix, à condition de créer une image conteneurisée qui la prend en charge.

  • Une image conteneurisée dans laquelle empaqueter l'application à l'aide de Docker.

  • Un dépôt dans Artifact Registry pour stocker l'image Docker.

  • Stratégies de lancement définies sur l'image du conteneur qui contrôlent la manière dont une charge de travail peut être exécutée et limitent les capacités d'un opérateur de charge de travail malveillant.

Pour déployer la charge de travail, une VM Confidential est exécutée par un opérateur de charge de travail basé sur l'image Confidential Space. L'image conteneurisée est ainsi récupérée à partir d'Artifact Registry et exécutée.

Les collaborateurs de données doivent valider les attestations d'une charge de travail avant qu'elle ne puisse accéder à leurs données.

Avant de commencer

Écrire une charge de travail pour Confidential Space ne se limite pas au code et au débogage. Vous devez également discuter avec les collaborateurs chargés des données pour évaluer leurs besoins, configurer votre environnement, empaqueter votre code dans une image conteneurisée et collaborer avec un opérateur de charge de travail pour vous assurer que tout se déploie correctement.

Discuter avec les collaborateurs pour les données

Avant de commencer à écrire votre application, vous devez discuter avec vos collaborateurs sur les données privées sur lesquelles ils souhaitent que vous travailliez. Vous pouvez poser les questions suivantes:

  • Quels sont les ID d'organisation concernés ?

  • Quels sont les numéros de projet concernés ?

  • Quelles sont les ressources Google Cloud auxquelles je dois accéder, et quels sont leurs ID et leurs noms ?

  • Existe-t-il des ressources auxquelles je dois accéder qui ne sont pas gérées par l'IAM Google Cloud ?

  • Comment l'application doit-elle comparer et traiter les données privées ?

  • Sous quel format doit être la sortie ?

  • Où doit être stockée la sortie et doit-elle être chiffrée ?

  • Tous les collaborateurs sur les données voient-ils le même résultat, ou les résultats sont-ils uniques pour chacun ?

De plus, chaque collaborateur de données peut également avoir des exigences de confidentialité uniques que vous devez respecter. Il est essentiel qu'aucune donnée privée ne soit exposée à la suite d'une charge de travail.

Créer votre solution Confidential Space

Il est utile de configurer deux projets (ou plus) avec les autorisations appropriées en tant qu'environnement de test, comme dans Créer votre premier environnement Confidential Space. Essayez de reproduire au mieux la configuration des projets des collaborateurs pour les données. Vous pourrez ainsi vous familiariser avec les autorisations interprojets et récupérer les données dont vous avez besoin à partir de ressources Google Cloud spécifiques. Vous pouvez également mieux comprendre les rôles d'opérateur de charge de travail et de collaborateur de données et leurs responsabilités.

Au cours de la première phase de compilation, il est utile d'observer les pratiques suivantes:

  • Lorsque vous travaillez en tant que collaborateur de données, limitez la validation des attestations au minimum pour accélérer le développement.

  • Lorsque vous travaillez en tant qu'opérateur de charge de travail, utilisez l'image de débogage Confidential Space au lieu de la production lorsque vous déployez la charge de travail. Vous disposez ainsi de plus de moyens de résoudre les problèmes de charge de travail.

À mesure que votre application évolue et que son état devient plus prévisible, vous pouvez verrouiller de plus en plus votre solution avec la validation des attestations et les règles de lancement, et passer à l'image de production de l'Confidential Space.

Une fois que votre charge de travail fonctionne correctement dans votre environnement de test, vous pouvez passer aux tests dans les projets de vos collaborateurs pour les données avec des ressources réelles, mais des données factices afin de leur montrer comment tout fonctionne. À ce stade, vous pouvez commencer à travailler avec un opérateur de charge de travail indépendant.

Lorsque tout fonctionne et que le résultat est conforme aux attentes, vous pouvez commencer à tester les données de production. Une fois les tests terminés et que toutes les parties ont approuvé les résultats, la charge de travail est prête à être mise en production.

Attention à la sortie

Lorsque vous testez votre code, il peut être tentant de déboguer en imprimant dans STDOUT ou STDERR. Si vous choisissez de le faire, veillez à ne pas exposer de données privées que d'autres parties pourraient lire en accédant aux journaux. Avant que votre code ne commence à fonctionner en production, assurez-vous qu'il n'affiche rien d'autre que ce qui est strictement nécessaire.

Il en va de même pour le résultat final. Ne fournissez qu'un résultat final qui ne compromet pas la confidentialité et la sensibilité des données d'origine.

Créer une image conteneurisée avec Docker

Les applications doivent être empaquetées dans une image conteneurisée créée par Docker, qui est stockée dans Artifact Registry. Lorsqu'une charge de travail est déployée, l'image Docker est extraite du dépôt Artifact Registry par l'image de l'Confidential Space, exécutée, et l'application peut commencer à travailler sur les ressources de projet appropriées.

Lorsque vous créez votre image Docker, tenez compte des points suivants:

Limites de disque et de mémoire

Confidential Space redimensionne automatiquement la partition d'état du disque de démarrage lorsque vous utilisez des tailles de disque de démarrage plus importantes. La taille de la partition correspond à peu près à la taille du disque de démarrage moins 5 Go.

Dans le cadre des protections du système de fichiers d'intégrité de Confidential Space, Confidential Space stocke des balises d'intégrité de disque en mémoire. Cela utilise environ 1% de surcharge de mémoire pour chaque octet de disque. Par exemple, un disque de 100 Go nécessite 1 Go de mémoire, et un disque de 10 To nécessite 100 Go de mémoire.

Veillez à respecter les limites de mémoire de la VM. La mémoire d'échange est désactivée sur les VM Confidential Space, ce qui signifie qu'une utilisation excessive de la mémoire peut planter la charge de travail. Assurez-vous que la machine que vous sélectionnez est compatible avec l'utilisation de la mémoire de votre charge de travail, en plus des frais généraux liés à l'intégrité du disque.

Jetons OIDC expirés

Un jeton OIDC est mis à la disposition de votre charge de travail au démarrage. Il contient des revendications d'attestation validées sur la VM de votre charge de travail et il est stocké dans le conteneur de charge de travail à l'emplacement /run/container_launcher/attestation_verifier_claims_token. Le jeton expire au bout de 60 minutes.

Si le jeton expire, une actualisation est effectuée en arrière-plan avec un intervalle exponentiel entre les tentatives jusqu'à ce que la requête aboutisse. Si une actualisation échoue (en raison de problèmes réseau, d'une interruption du service d'attestation ou pour toute autre raison), votre code de charge de travail doit pouvoir gérer cette défaillance.

Votre charge de travail peut gérer l'échec de l'actualisation des jetons de l'une des manières suivantes :

  • Ignorer le jeton expiré, en supposant qu'il n'est plus requis après l'utilisation initiale.

  • Attendre que le jeton arrivé à expiration soit actualisé.

  • Quitter la charge de travail.

Montages de mémoire tampon en mémoire

Confidential Space permet d'ajouter des espaces de travail temporaires en mémoire. Cela utilise la mémoire disponible dans la VM Confidential Space. Étant donné que l'espace de travail utilise la mémoire de la VM confidentielle, il présente les mêmes propriétés d'intégrité et de confidentialité que la VM confidentielle.

Vous pouvez utiliser tee-dev-shm-size pour augmenter la taille de l'installation de mémoire partagée /dev/shm pour la charge de travail. La taille de /dev/shm est spécifiée en Ko.

Vous pouvez utiliser tee-mount pour spécifier les montages tmpfs dans le conteneur en cours d'exécution à l'aide de configurations séparées par une virgule. Les valeurs type et source sont toujours tmpfs. destination est le point d'installation, qui interagit avec la stratégie de lancement tee.launch_policy.allow_mount_destinations. Vous pouvez éventuellement spécifier la taille de tmpfs en octets. La taille par défaut est de 50% de la mémoire de la VM.

Ports entrants

Par défaut, les VM Confidential Space fonctionnent avec une règle de pare-feu qui bloque tous les ports entrants. Lorsque vous utilisez une image Confidential Space version 230600 ou ultérieure, vous pouvez spécifier des ports entrants à garder dans Dockerfile lors de la création de votre image de charge de travail.

Pour ouvrir des ports, ajoutez le mot-clé EXPOSE à votre fichier Dockerfile, ainsi que le numéro de port à laisser ouvert et un protocole facultatif de tcp ou udp. Si vous ne spécifiez pas le protocole pour un port, TCP et UDP sont tous les deux autorisés. Voici un exemple de Dockerfile qui expose des ports entrants:

FROM alpine:latest
EXPOSE 80
EXPOSE 443/tcp
EXPOSE 81/udp
WORKDIR /test
COPY salary /test
ENTRYPOINT ["/test/salary"]
CMD []

Selon l'image de base que vous utilisez, certains ports peuvent déjà être exposés. Votre Dockerfile n'expose que des ports supplémentaires. Il ne peut pas bloquer les ports déjà ouverts par l'image de base.

Les opérateurs de charge de travail doivent s'assurer que les ports exposés sont ouverts dans leur pare-feu VPC avant d'exécuter la charge de travail. Les numéros de port peuvent être fournis par l'auteur de la charge de travail ou extraits des informations sur l'image Docker.

Les ports exposés sont consignés dans la console et redirigés vers Cloud Logging lorsque vous utilisez la variable de métadonnées tee-container-log-redirect.

Règles de lancement

Les règles de lancement remplacent les variables de métadonnées de VM définies par les opérateurs de charge de travail pour limiter les actions malveillantes. Un auteur de charge de travail peut définir des stratégies avec un libellé lors de la création de son image de conteneur.

Par exemple, dans un Dockerfile:

LABEL "tee.launch_policy.allow_cmd_override"="true"

Dans un fichier BUILD Bazel :

container_image(
    ...
    labels={"tee.launch_policy.allow_cmd_override":"true"}
    ...
)

Les règles de lancement disponibles sont listées dans le tableau suivant :

Règle Type Description

tee.launch_policy.allow_cmd_override

Interagit avec:

Valeur booléenne (false par défaut) Détermine si le CMD spécifié dans le Dockerfile du conteneur de charge de travail peut être remplacé par un opérateur de charge de travail avec la valeur de métadonnées tee-cmd.

tee.launch_policy.allow_env_override

Interagit avec:

Chaîne séparée par une virgule Chaîne de noms de variable d'environnement autorisés, séparés par une virgule, pouvant être définis par un opérateur de charge de travail avec des valeurs de métadonnées tee-env-ENVIRONMENT_VARIABLE_NAME.

tee.launch_policy.allow_mount_destinations

Interagit avec:

  • Opérateur de charge de travail: variable de métadonnées tee-mount.
Chaîne séparée par des deux-points

Chaîne de répertoires d'installation autorisés, séparés par deux-points, que l'opérateur de charge de travail est autorisé à installer à l'aide de tee-mount.

Par exemple : /run/tmp:/var/tmp:/tmp

tee.launch_policy.log_redirect

Interagit avec:

Chaîne définie

Détermine le fonctionnement de la journalisation si tee-container-log-redirect est défini sur true par un opérateur de charge de travail.

Les valeurs valides sont les suivantes:

  • debugonly (par défaut): n'autorisez que les redirections stdout et stderr si vous utilisez une image de débogage.
  • always: autorisez toujours les redirections stdout et stderr.
  • never: n'autorisez jamais les redirections stdout et stderr.

tee.launch_policy.monitoring_memory_allow

Interagit avec:

Chaîne définie

Détermine le fonctionnement de la surveillance de l'utilisation de la mémoire de la charge de travail si tee-memory-monitoring-enable est défini sur true par un opérateur de charge de travail.

Les valeurs valides sont les suivantes:

  • debugonly (par défaut): n'autorisez la surveillance de l'utilisation de la mémoire que si vous utilisez une image de débogage.
  • always: autorise toujours la surveillance de l'utilisation de la mémoire.
  • never: n'autorise jamais la surveillance de l'utilisation de la mémoire.

Exécutions multiples de charge de travail

Pour garantir un environnement propre, une VM doit redémarrer avant de redémarrer une charge de travail. Cela chiffre le disque de la VM avec une clé éphémère, afin de traiter le vecteur d'attaque de la modification d'une image de charge de travail sur le disque après son téléchargement et son évaluation.

Cela augmente également les frais généraux, tels que le temps de démarrage et l'extraction de l'image de charge de travail à chaque exécution de charge de travail. Si ces surcharges affectent trop les performances de votre charge de travail, vous pouvez coder un redémarrage de charge de travail dans la charge de travail elle-même, au prix d'une augmentation de votre profil de risque.

Images de conteneurs reproductibles

Créer une image de conteneur de manière reproductible permet de renforcer la confiance entre les parties. Vous pouvez créer des images reproductibles avec Bazel.

Ressources non gérées par l'IAM Google Cloud

Pour accéder aux ressources non gérées par l'IAM Google Cloud , votre charge de travail doit spécifier une audience personnalisée.

Pour en savoir plus, consultez la section Accéder aux ressources non gérées par l'IAM Google Cloud .

Images de conteneurs signées

Vous pouvez signer une image de conteneur avec une clé publique, que le collaborateur de données peut ensuite utiliser pour l'attestation au lieu de spécifier un récapitulatif d'image dans sa règle de travail en cours.

Cela signifie que les collaborateurs de données n'ont pas besoin de mettre à jour leurs règles de travail en cours à chaque mise à jour d'une charge de travail, et que la charge de travail peut continuer à accéder aux ressources protégées sans interruption.

Vous pouvez utiliser la cosignature Sigstore pour signer l'image du conteneur. Pour s'assurer que Confidential Space peut récupérer les signatures, les opérateurs de charge de travail doivent ajouter les informations de signature à la variable de métadonnées tee-signed-image-repos avant de déployer la charge de travail.

Lors de l'exécution, les signatures sont envoyées au service d'attestation Confidential Space pour validation. Le service d'attestation renvoie un jeton de revendications d'attestation contenant les revendications de signature validées. Voici un exemple de revendication de signature:

"image_signatures": [
  {
    "key_id": "hexadecimal-sha256-fingerprint-public-key1",
    "signature": "base64-encoded-signature",
    "signature_algorithm": "RSASSA_PSS_SHA256"
  },
  {
    "key_id": "hexadecimal-sha256-fingerprint-public-key2",
    "signature": "base64-encoded-signature",
    "signature_algorithm": "RSASSA_PSS_SHA256",
  },
  {
    "key_id": "hexadecimal-sha256-fingerprint-public-key3",
    "signature": "base64-encoded-signature",
    "signature_algorithm": "RSASSA_PSS_SHA256",
  }
],

Pour configurer la signature des images de conteneur, consultez l'atelier de programmation Image de conteneur signée.