Ce tutoriel explique comment configurer et tester une stratégie d'autorisation binaire exigeant des attestations. Ce type de stratégie sécurise votre chaîne d'approvisionnement logicielle basée sur des conteneurs en vérifiant qu'une image de conteneur dispose d'une attestation signée avant d'autoriser son déploiement.
Au moment du déploiement, l'autorisation binaire utilise des certificateurs pour valider les signatures numériques figurant dans les attestations. Les attestations sont créées par des signers, généralement dans le cadre d'un pipeline d'intégration continue (CI).
Dans ce tutoriel, le cluster GKE, les attestations et les certificateurs se trouvent tous dans le même projet. L'intérêt d'une configuration à projet unique est principalement de tester et réaliser des expériences avec le service. Pour obtenir un exemple plus concret, consultez la page Configuration multiprojets.
Les étapes ci-dessous décrivent les tâches que vous effectuez en ligne de commande. Pour effectuer ces étapes avec la console Google Cloud, consultez la page Premiers pas avec la console Google Cloud.
Objectifs
Dans ce tutoriel, vous allez apprendre à effectuer les opérations suivantes :
- Créer un cluster Google Kubernetes Engine (GKE) avec l'autorisation binaire activée
- Créer un certificateur utilisé par l'outil d'application de l'autorisation binaire pour valider la signature d'une attestation
- Configurer une stratégie exigeant une attestation
- Créer une paire de clés cryptographiques pour signer les attestations puis les valider
- Signer un condensé d'image de conteneur pour générer une signature
- Créer une attestation à l'aide de la signature
- Tester la stratégie en déployant une image de conteneur sur GKE
Coûts
Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :
- Artifact Registry or Container Registry
- Binary Authorization
- GKE
- Optional: Cloud Key Management Service
Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût.
Avant de commencer
- Connectez-vous à votre compte Google Cloud. Si vous débutez sur Google Cloud, créez un compte pour évaluer les performances de nos produits en conditions réelles. Les nouveaux clients bénéficient également de 300 $ de crédits gratuits pour exécuter, tester et déployer des charges de travail.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
- Installez
kubectl
pour interagir avec GKE.
Activer l'autorisation binaire
Définir le projet par défaut
La première étape consiste à définir le projet Google Cloud par défaut utilisé par la commande gcloud
:
PROJECT_ID=PROJECT_ID gcloud config set project ${PROJECT_ID}
Où PROJECT_ID correspond au nom de votre projet.
Activer les API requises
Activez les API pour :
Container Registry
gcloud --project=${PROJECT_ID} \ services enable\ container.googleapis.com\ containerregistry.googleapis.com\ binaryauthorization.googleapis.com
Artifact Registry
gcloud --project=${PROJECT_ID} \ services enable\ container.googleapis.com\ artifactregistry.googleapis.com\ binaryauthorization.googleapis.com
Créer un cluster avec l'autorisation binaire activée
Créer le cluster
Créer un cluster GKE avec l'autorisation binaire activée Il s'agit du cluster dans lequel vous souhaitez exécuter les images de conteneur que vous déployez. Lorsque vous créez le cluster, vous transmettez l'option --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE
à la commande gcloud container clusters create
.
Pour créer le cluster, procédez comme suit :
gcloud container clusters create \ --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE \ --zone us-central1-a \ test-cluster
Ici, vous créez un cluster nommé test-cluster
dans la zone GKE us-central1-a
.
Configurer kubectl
Vous devez également mettre à jour le fichier kubeconfig
local pour votre installation kubectl
. Cela fournit les identifiants et les informations de point de terminaison requis pour accéder au cluster dans GKE.
Pour mettre à jour le fichier kubeconfig
local, exécutez la commande suivante :
gcloud container clusters get-credentials \ --zone us-central1-a \ test-cluster
Afficher la stratégie par défaut
Dans l'autorisation binaire, une stratégie est un ensemble de règles régissant le déploiement d'une ou plusieurs images de conteneurs. Vous pouvez définir une stratégie par projet. Par défaut, la stratégie est configurée pour autoriser le déploiement de toutes les images de conteneurs.
L'autorisation binaire vous permet d'exporter et d'importer un fichier de stratégie au format YAML. Ce format reflète la structure d'une stratégie telle qu'elle est stockée par le service. Lorsque vous configurez une stratégie à l'aide des commandes gcloud
, vous modifiez ce fichier.
Pour afficher la stratégie par défaut, exportez le fichier YAML de stratégie :
gcloud container binauthz policy export
Par défaut, ce fichier comporte les éléments suivants :
defaultAdmissionRule: enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG evaluationMode: ALWAYS_ALLOW globalPolicyEvaluationMode: ENABLE name: projects/PROJECT_ID/policy
La règle par défaut est définie dans le nœud defaultAdmissionRule
. evaluationMode
indique que la stratégie autorise toutes les tentatives lors du déploiement de l'image. Dans ce tutoriel, vous allez mettre à jour la règle par défaut afin d'exiger des attestations.
globalPolicyEvaluationMode
exclut les images système gérées par Google de l'application de l'autorisation binaire.
Pour ajouter une image exclue à la liste d'autorisation, ajoutez le code suivant au fichier de règles :
admissionWhitelistPatterns: - namePattern: EXEMPT_IMAGE_PATH
Remplacez EXEMPT_IMAGE_PATH
par le chemin d'accès à l'image que vous souhaitez exclure. Pour exclure des images supplémentaires, ajoutez d'autres entrées - namePattern
. En savoir plus sur admissionWhitelistPatterns
.
Pour en savoir plus sur la structure d'une stratégie, consultez la documentation de référence sur les fichiers YAML de stratégie.
Créer un certificateur
Un certificateur est l'autorité de validation utilisée par l'outil d'application de l'autorisation binaire au moment du déploiement pour décider d'autoriser ou non GKE à déployer l'image de conteneur signée correspondante. Le certificateur contient la clé publique et, en règle générale, il est géré par les personnes qui, dans votre organisation, sont responsables de la sécurité de la chaîne d'approvisionnement logicielle.
Pour créer un certificateur, vous devez effectuer les actions suivantes :
- Créer une note dans Artifact Analysis pour stocker les métadonnées de confiance utilisées dans le processus d'autorisation.
- Créer le certificat proprement dit dans l'autorisation binaire et lui associer la note que vous avez créée.
Pour ce tutoriel, vous disposez d'un certificateur nommé test-attestor
et d'une note Container Analysis nommée test-attestor-note
. Dans un scénario réel, vous pouvez avoir un nombre illimité de certificateurs, chacun représentant une partie prenante du processus d'autorisation de l'image de conteneur.
Créer la note Artifact Analysis
Définissez des variables qui stockent le nom de votre certificateur et la note Artifact Analysis :
ATTESTOR_NAME=test-attestor NOTE_ID=test-attestor-note
Remplacez :
- test-attestor : nom du certificateur de votre choix.
- attestor-note : nom de la note de certificateur de votre choix.
Créez un fichier JSON décrivant la note Container Analysis dans
/tmp/note_payload.json
:cat > /tmp/note_payload.json << EOM { "name": "projects/${PROJECT_ID}/notes/${NOTE_ID}", "attestation": { "hint": { "human_readable_name": "Attestor Note" } } } EOM
Créez la note en envoyant une requête HTTP à l'API REST Artifact Analysis :
curl -X POST \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ --data-binary @/tmp/note_payload.json \ "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"
Vérifiez que la note a bien été créée :
curl \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"
Créer le certificateur
Vous pouvez maintenant créer le certificateur.
Créez le certificateur dans l'autorisation binaire :
gcloud container binauthz attestors create ${ATTESTOR_NAME} \ --attestation-authority-note=${NOTE_ID} \ --attestation-authority-note-project=${PROJECT_ID}
Vérifiez que le certificateur a bien été créé :
gcloud container binauthz attestors list
Le certificateur que vous avez créé n'est pas utilisable sans paire de clés PKIX associée. Vous allez la créer ci-dessous.
Générer une paire de clés
L'autorisation binaire utilise des clés cryptographiques pour vérifier de manière sécurisée l'identité des signers. Cela garantit que seules les images de conteneurs autorisées peuvent être déployées. La paire de clés comprend une clé privée et une clé publique. Le signer utilise la clé privée pour signer le condensé de l'image de conteneur, produisant ainsi une signature qui est ensuite stockée dans une attestation. La clé publique est stockée dans le certificateur. Au moment du déploiement, l'outil d'application de l'autorisation binaire utilise la clé publique du certificateur pour valider la signature figurant dans l'attestation, avant d'autoriser le déploiement du conteneur.
Dans ce tutoriel, vous allez utiliser le format d'infrastructure à clé publique X.509 (PKIX) pour les clés cryptographiques. Ce tutoriel utilise l'algorithme de signature numérique à courbe elliptique (ECDSA) recommandé pour générer une paire de clés PKIX. Vous pouvez également utiliser des clés RSA ou PGP pour la signature.
Consultez la page Objectifs et algorithmes des clés pour plus d'informations sur les algorithmes de signature.
Les clés générées et stockées par le service Cloud Key Management Service (Cloud KMS) sont compatibles avec PKIX. Consultez la page Créer des certificateurs à l'aide de la CLI gcloud pour plus d'informations sur l'utilisation des clés PKIX et de Cloud KMS.
PKIX (Cloud KMS)
Pour créer la paire de clés dans Cloud KMS, procédez comme suit :
Configurez les variables d'environnement nécessaires à la création de la paire de clés.
KMS_KEY_PROJECT_ID=${PROJECT_ID} KMS_KEYRING_NAME=my-binauthz-keyring KMS_KEY_NAME=my-binauthz-kms-key-name KMS_KEY_LOCATION=global KMS_KEY_PURPOSE=asymmetric-signing KMS_KEY_ALGORITHM=ec-sign-p256-sha256 KMS_PROTECTION_LEVEL=software KMS_KEY_VERSION=1
Pour créer le trousseau, exécutez la commande suivante :
gcloud kms keyrings create ${KMS_KEYRING_NAME} \ --location ${KMS_KEY_LOCATION}
Pour créer la clé, exécutez la commande suivante :
gcloud kms keys create ${KMS_KEY_NAME} \ --location ${KMS_KEY_LOCATION} \ --keyring ${KMS_KEYRING_NAME} \ --purpose ${KMS_KEY_PURPOSE} \ --default-algorithm ${KMS_KEY_ALGORITHM} \ --protection-level ${KMS_PROTECTION_LEVEL}
Pour ajouter la clé publique au certificateur, exécutez la commande suivante :
gcloud --project="${PROJECT_ID}" \ container binauthz attestors public-keys add \ --attestor="${ATTESTOR_NAME}" \ --keyversion-project="${KMS_KEY_PROJECT_ID}" \ --keyversion-location="${KMS_KEY_LOCATION}" \ --keyversion-keyring="${KMS_KEYRING_NAME}" \ --keyversion-key="${KMS_KEY_NAME}" \ --keyversion="${KMS_KEY_VERSION}"
Obtenez l'ID de clé publique auprès du certificateur comme suit :
Vous pouvez afficher l'ID de votre clé publique à tout moment à l'aide de la commande
gcloud container binauthz attestors describe <var>ATTESTOR_NAME</var>
.Pour enregistrer votre ID de clé publique dans une variable d'environnement, saisissez la commande suivante :
PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \ --format='value(userOwnedGrafeasNote.publicKeys[0].id)' --project ${PROJECT_ID})
PKIX (clé locale)
Pour générer une paire de clés PKIX, procédez comme suit :
Créez la clé privée :
PRIVATE_KEY_FILE="/tmp/ec_private.pem" openssl ecparam -genkey -name prime256v1 -noout -out ${PRIVATE_KEY_FILE}
Extrayez la clé publique de la clé privée :
PUBLIC_KEY_FILE="/tmp/ec_public.pem" openssl ec -in ${PRIVATE_KEY_FILE} -pubout -out ${PUBLIC_KEY_FILE}
Ajoutez la clé publique au certificateur.
Ajoutez maintenant au certificateur la clé publique que vous avez exportée, pour qu'elle puisse être utilisée par l'autorisation binaire pour la validation de l'identité :
gcloud --project="${PROJECT_ID}" \ beta container binauthz attestors public-keys add \ --attestor="${ATTESTOR_NAME}" \ --pkix-public-key-file=${PUBLIC_KEY_FILE} \ --pkix-public-key-algorithm=ecdsa-p256-sha256
Enregistrez l'ID de la clé publique.
Pour enregistrer l'ID de clé publique, vous pouvez le copier à partir du résultat de la commande
public-keys add
figurant ci-dessus. Pour afficher l'ID de clé publique de votre certificateur après son ajout, utilisez la commandegcloud container binauthz attestors describe ${ATTESTOR_NAME}
:PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \ --format='value(userOwnedGrafeasNote.publicKeys[0].id)')
Configurer la stratégie
Vous pouvez maintenant configurer votre stratégie. Au cours de cette étape, vous exportez le fichier YAML de stratégie vers votre système local et modifiez la règle par défaut de sorte qu'elle nécessite une attestation de la part du certificateur que vous avez défini ci-dessus.
Pour configurer la stratégie, procédez comme suit :
Créez un fichier de stratégie qui autorise les images système gérées par Google, définit
evaluationMode
surREQUIRE_ATTESTATION
et ajoute un nœud nommérequireAttestationsBy
qui référence le certificateur que vous avez créé :cat > /tmp/policy.yaml << EOM globalPolicyEvaluationMode: ENABLE defaultAdmissionRule: evaluationMode: REQUIRE_ATTESTATION enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG requireAttestationsBy: - projects/${PROJECT_ID}/attestors/${ATTESTOR_NAME} name: projects/${PROJECT_ID}/policy EOM
Importez le fichier YAML de stratégie dans l'autorisation binaire :
gcloud container binauthz policy import /tmp/policy.yaml
Pour plus d'informations sur la configuration des stratégies, consultez la page Configurer une stratégie à l'aide de la CLI gcloud.
Tester la stratégie
Vous pouvez tester la stratégie que vous avez configurée ci-dessus en essayant de déployer un exemple d'image de conteneur sur le cluster. La stratégie va bloquer le déploiement, car l'attestation requise n'a pas été réalisée.
Pour ce tutoriel, vous pouvez utiliser des exemples d'images de Container Registry et d'Artifact Registry. L'image de Container Registry se trouve dans le chemin gcr.io/google-samples/hello-app:1.0
. L'image d'Artifact Registry se trouve dans le chemin us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
.
Les deux chemins d'accès contiennent une image publique créée par Google et contenant un exemple d'application "Hello, World!".
Commencez par essayer de déployer l'image :
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
Maintenant, vérifiez que le déploiement a été bloqué par l'autorisation binaire :
kubectl get pods
La commande affiche le message suivant, qui indique que l'image n'a pas été déployée :
No resources found.
Vous pouvez obtenir plus de détails sur le déploiement avec la commande suivante :
kubectl get event --template \ '{{range.items}}{{"\033[0;36m"}}{{.reason}}:{{"\033[0m"}}\{{.message}}{{"\n"}}{{end}}'
Une réponse semblable à celle-ci s'affiche :
FailedCreate: Error creating: pods POD_NAME is forbidden: admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image IMAGE_NAME denied by Binary Authorization default admission rule. Image IMAGE_NAME denied by attestor ATTESTOR_NAME: No attestations found
Dans ce résultat :
- POD_NAME : nom du pod.
- IMAGE_NAME : nom de l'image.
- ATTESTOR_NAME : nom du certificateur.
Veillez à supprimer le déploiement pour pouvoir passer à l'étape suivante :
kubectl delete deployment hello-server
Créez un certificat
Une attestation est un document numérique créé par un signer certifiant que GKE est autorisé à déployer l'image de conteneur associée. Le processus de création d'une attestation est parfois appelé "signature d'une image". Un signataire peut être une personne ou, plus souvent, un processus automatisé qui s'exécute à la création d'une image de conteneur. La signature est créée à l'aide de la clé privée provenant d'une paire de clés. Au moment du déploiement, l'outil d'application de l'autorisation binaire utilise la clé publique du certificateur pour valider la signature dans l'attestation.
Dans ce tutoriel, votre attestation indique simplement que vous autorisez l'image en vue du déploiement.
Pour créer une attestation, procédez comme suit :
Définissez les variables qui stockent le chemin d'accès au registre et le condensé de l'image :
Container Registry
IMAGE_PATH="gcr.io/google-samples/hello-app" IMAGE_DIGEST="sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea882eb722c3be4" IMAGE_TO_ATTEST=${IMAGE_PATH}@${IMAGE_DIGEST}
Artifact Registry
IMAGE_PATH="us-docker.pkg.dev/google-samples/containers/gke/hello-app" IMAGE_DIGEST="sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567" IMAGE_TO_ATTEST=${IMAGE_PATH}@${IMAGE_DIGEST}
Pour créer l'attestation, procédez comme suit :
PKIX Cloud KMS
Pour créer l'attestation à l'aide de la clé Cloud KMS, exécutez la commande suivante :
gcloud beta container binauthz attestations sign-and-create \ --project="${PROJECT_ID}" \ --artifact-url="${IMAGE_TO_ATTEST}" \ --attestor="${ATTESTOR_NAME}" \ --attestor-project="${PROJECT_ID}" \ --keyversion-project="${KMS_KEY_PROJECT_ID}" \ --keyversion-location="${KMS_KEY_LOCATION}" \ --keyversion-keyring="${KMS_KEYRING_NAME}" \ --keyversion-key="${KMS_KEY_NAME}" \ --keyversion="${KMS_KEY_VERSION}"
PKIX (clé locale)
Pour créer l'attestation à l'aide de la clé locale, procédez comme suit :
Générez la charge utile de l'attestation :
gcloud container binauthz create-signature-payload \ --artifact-url=${IMAGE_TO_ATTEST} > /tmp/generated_payload.json
Le contenu du fichier JSON de charge utile obtenu est le suivant :
{ "critical": { "identity": { "docker-reference": "gcr.io/google-samples/hello-app" }, "image": { "docker-manifest-digest": "sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea 882eb722c3be4" }, "type": "Google cloud binauthz container signature" } }
Pour signer la charge utile avec votre clé privée PKIX et générer un fichier de signature, exécutez la commande suivante :
openssl dgst -sha256 -sign ${PRIVATE_KEY_FILE} /tmp/generated_payload.json > /tmp/ec_signature
Le fichier de signature est la version signée du fichier JSON de charge utile que vous avez créé précédemment dans ce guide.
Créez et validez l'attestation :
gcloud container binauthz attestations create \ --project="${PROJECT_ID}" \ --artifact-url="${IMAGE_TO_ATTEST}" \ --attestor="projects/${PROJECT_ID}/attestors/${ATTESTOR_NAME}" \ --signature-file=/tmp/ec_signature \ --public-key-id="${PUBLIC_KEY_ID}" \ --validate
Remplacez
PUBLIC_KEY_ID
par l'ID de clé publique que vous avez déterminé à la section Générer une paire de clés PKIX ci-dessus.L'option
validate
vérifie que l'attestation peut être validée par le certificateur que vous avez configuré dans votre stratégie.
Vérifiez que l'attestation a bien été créée :
gcloud container binauthz attestations list \ --attestor=$ATTESTOR_NAME --attestor-project=$PROJECT_ID
Pour en savoir plus sur la création d'attestations, consultez la page Créer des attestations.
Tester une nouvelle fois la stratégie
Testez une nouvelle fois la stratégie en déployant un exemple d'image de conteneur sur le cluster.
Cette fois, vous devez déployer l'image à l'aide du condensé au lieu d'un tag tel que 1.0
ou latest
, car l'autorisation binaire utilise le condensé pour rechercher les attestations. Ici, l'autorisation binaire permet le déploiement de l'image, car l'attestation requise a été réalisée.
Pour déployer l'image, exécutez la commande suivante :
kubectl run hello-server --image ${IMAGE_TO_ATTEST} --port 8080
Pour vérifier que l'image a été déployée :
kubectl get pods
La commande imprime un message semblable à celui ci-dessous, indiquant que le déploiement a bien été effectué :
NAME READY STATUS RESTARTS AGE hello-server-579859fb5b-h2k8s 1/1 Running 0 1m
Effectuer un nettoyage
Pour éviter que les ressources utilisées lors de ce tutoriel soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et supprimez les ressources individuelles.
Supprimez le cluster que vous avez créé dans GKE :
gcloud container clusters delete \ --zone=us-central1-a \ test-cluster
Étape suivante
- Obtenez davantage d'informations sur l'autorisation binaire.
- Découvrez les concepts clés utilisés dans l'autorisation binaire.
- Utilisez le certificateur
built-by-cloud-build
pour déployer uniquement des images créées par Cloud Build (bêta). - Activez le mode de simulation pour modifier le mode d'application d'une stratégie.
- Utilisez le mode "bris de glace" pour contourner l'application.