Intégrer Cloud Run et la fédération d'identité de charge de travail

Restez organisé à l'aide des collections Enregistrez et classez les contenus selon vos préférences.

Ce tutoriel explique comment utiliser la fédération d'identité de charge de travail pour authentifier les charges de travail exécutées en dehors de Google Cloud afin qu'elles puissent accéder aux microservices hébergés par Cloud Run. Ce tutoriel est destiné aux administrateurs qui souhaitent intégrer la fédération d'identité de charge de travail à leur fournisseur d'identité existant. La fédération d'identité de charge de travail vous permet de connecter des charges de travail externes à des charges de travail exécutées dans Google Cloud. Cloud Run vous permet d'exécuter des microservices conteneurisés sans état.

Ce tutoriel fournit des instructions pour configurer Jenkins en tant que charge de travail externe, Keycloak en tant que fournisseur d'identité, Cloud Run et fédération d'identité de charge de travail. Une fois que vous aurez terminé ce tutoriel, vous verrez comment la fédération d'identité de charge de travail vous permet d'authentifier votre application Jenkins avec Google Cloud à l'aide de l'authentification OpenID Connect.

Authentification externe des charges de travail à l'aide de clés de compte de service

Si une charge de travail s'exécute en dehors de Google Cloud, vous devez l'authentifier de manière sécurisée pour qu'elle puisse interagir avec votre microservice hébergé par Cloud Run. Traditionnellement, vous pouvez utiliser un outil tel que les bibliothèques clientes Cloud pour vous authentifier et transmettre une clé de compte de service afin de réaliser une authentification avec une charge de travail externe. Les bibliothèques clientes Cloud utilisent une bibliothèque appelée ADC (Application Default Credentials) pour rechercher automatiquement vos identifiants de compte de service. Cette bibliothèque définit une variable d'environnement appelée GOOGLE_APPLICATION_CREDENTIALS. L'ADC utilise la clé de compte de service ou le fichier de configuration vers lequel pointe la variable afin d'authentifier automatiquement votre compte.

Toutefois, cette approche présente les risques de sécurité suivants :

  • Par défaut, une clé de compte de service n'inclut pas de date d'expiration. En cas de fuite de votre code, vous exposez chaque autorisation associée à cette clé.
  • Les clés de compte de service étant statiques, vous devez créer une stratégie pour les gérer et les alterner.

Même si la création d'une clé de compte de service est un processus relativement simple, vous pouvez sacrifier la sécurité pour plus de simplicité.

Authentification de la charge de travail externe à l'aide de la fédération d'identité de charge de travail

La fédération d'identité de charge de travail résout les risques de sécurité résultant de la création et du téléchargement des clés de compte de service statiques. La fédération d'identités de charge de travail vous permet d'authentifier les charges de travail en dehors de Google Cloud sans utiliser de clé de compte de service statique. Toutes les charges de travail externes qui doivent consommer des services dans Google Cloud peuvent bénéficier de cette fonctionnalité.

La fédération d'identité de charge de travail vous permet d'utiliser votre IdP pour vous authentifier directement auprès de Google Cloud. Pour vous authentifier, vous utilisez OpenID Connect. Cloud Run accepte les jetons OpenID Connect de votre fournisseur d'identité pour l'authentification.

Le processus d'authentification lors de l'utilisation de la fédération d'identité de charge de travail est le suivant :

  1. Votre bibliothèque d'authentification (AUTHN) envoie une requête de jeton Web JSON (JWT) au fournisseur d'identité.
  2. Votre fournisseur d'identité signe les jetons Web JSON (JWT). La bibliothèque AUTHN lit ces données à partir d'une variable.
  3. La bibliothèque envoie une commande POST au service de jetons de sécurité qui inclut le jeton signé.
  4. Security Token Service examine le fournisseur de pools de fédération d'identification de charge de travail que vous avez configuré pour créer une approbation et vérifie l'identité sur l'identifiant.
  5. Security Token Service renvoie un jeton fédéré.
  6. La bibliothèque envoie le jeton à IAM.
  7. Cloud IAM échange le jeton contre un jeton OpenID Connect d'un compte de service. Pour en savoir plus, consultez Générer des jetons d'identification OpenID Connect.
  8. La bibliothèque fournit le jeton OpenID Connect à Jenkins.
  9. Jenkins s'authentifie auprès de Cloud Run à l'aide de ce jeton.

Le schéma suivant illustre le flux d'authentification :

Flux d'authentification

Objectifs

  • Configurer Jenkins en tant que charge de travail externe.
  • Configurez Keycloak en tant que fournisseur d'identité compatible avec OpenID Connect.
  • Associez Jenkins à Keycloak.
  • Installez les bibliothèques clientes Cloud pour obtenir le jeton JWT de Keycloak vers Google Cloud.
  • Associez Google Cloud à Keycloak et Jenkins.
  • Obtenez le jeton JWT de l'utilisateur authentifié à partir de Keycloak.

Bien que ce tutoriel utilise Keycloak, vous pouvez utiliser n'importe quel fournisseur d'identité compatible avec OpenID Connect, tel que GitLab, Okta ou OneLogin.

Coûts

Ce tutoriel utilise les composants facturables suivants de Google Cloud :

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Une fois que vous avez terminé ce tutoriel, vous pouvez éviter de continuer à payer des frais en supprimant les ressources que vous avez créées. Pour en savoir plus, consultez la section Effectuer un nettoyage.

Avant de commencer

  1. Dans Google Cloud Console, accédez à la page de sélection du projet.

    Accéder au sélecteur de projet

  2. Sélectionnez ou créez un projet Google Cloud.

  3. Assurez-vous que la facturation est activée pour votre projet Cloud. Découvrez comment vérifier si la facturation est activée sur un projet.

  4. Configurez un microservice sur Cloud Run. Pour en savoir plus, consultez la page Guide de démarrage rapide : Déployer un conteneur dans Cloud Run.

Configurer Jenkins

Effectuez ces tâches dans un environnement autre que Google Cloud, tel que votre environnement sur site ou un autre cloud.

Si vous disposez déjà d'un fournisseur d'identité compatible avec OpenID Connect et d'une charge de travail externe, vous pouvez ignorer cette étape et passer à la section Installer les bibliothèques clientes Cloud.

Pour simuler une charge de travail externe, vous pouvez utiliser une VM sur laquelle Jenkins est installé. Vous pouvez exécuter Jenkins en tant qu'image Docker ou l'installer directement sur votre serveur. Les étapes suivantes montrent comment l'installer directement sur le serveur.

  1. Sur la VM de votre choix, ouvrez une ligne de commande.
  2. Installez Java :

    $ sudo apt update
    $ sudo apt install openjdk-11-jre
    $ java -version
    
  3. Installez Jenkins :

    curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo tee \
    /usr/share/keyrings/jenkins-keyring.asc > /dev/null
    echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
    https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
    /etc/apt/sources.list.d/jenkins.list > /dev/null
    sudo apt-get update
    sudo apt-get install jenkins
    
  4. Vérifiez que vous pouvez accéder à votre serveur Jenkins sur le port 8080. Si vous utilisez une VM protégée par un pare-feu, assurez-vous que les ports appropriés sont ouverts.

  5. Obtenez votre mot de passe administrateur et configurez Jenkins. Pour obtenir des instructions, consultez la page Assistant de configuration de l'installation.

  6. Effectuez les actions suivantes pour configurer SSL :

    1. Si vous disposez d'un fournisseur de domaine, vous pouvez utiliser son autorité de certification (CA) pour demander un certificat signé. Vous pouvez également obtenir un certificat signé gratuitement et valable 90 jours à partir de Zerossl.com.
    2. Téléchargez le fichier ZIP de votre certificat et transférez-le vers votre serveur qui exécute Jenkins :

      scp -i CERTFILE.pem -r CERTFILE.zip VM_FQDN:/home/USERNAME
      

      Remplacez les éléments suivants :

      • CERTFILE par le nom du fichier de certificat qui inclut votre clé publique.
      • VM_FQDN par le nom de domaine complet de votre serveur situé en dehors de Google Cloud.
      • USERNAME par votre nom d'utilisateur.
    3. Renommez les fichiers et générez un fichier .pkcs12 que Jenkins peut utiliser :

      openssl rsa -in KEYFILE.com.key -out KEYFILE.com.key

      Remplacez KEYFILE par le nom du fichier de certificat.

  7. Mettez à jour le fichier /etc/sysconfig/jenkins :

    1. Ouvrez le fichier dans un éditeur de texte :

      vi /etc/sysconfig/jenkins
      
    2. Définissez JENKINS_PORT sur -1.

    3. Définissez JENKINS_HTTPS_PORT sur 8443.

    4. Au bas du fichier, ajoutez les arguments suivants :

      JENKINS_ARGS="--httpsCertificate=/var/lib/jenkins/.ssl/CERTFILE.crt --httpsPrivateKeys=/var/lib/jenkins/.ssl/KEYFILE.pkcs1.key"

      Remplacez les éléments suivants :

      • CERTFILE par le nom du fichier de certificat au format .crt.
      • KEYFILE par le nom de fichier de la clé PKCS.
  8. Redémarrez votre serveur Jenkins.

  9. Vérifiez que le port 8443 de votre pare-feu est ouvert et accédez à Jenkins sur le port 8443.

  10. Installez un plug-in Jenkins dont vous avez besoin pour intégrer Keycloak à Jenkins. Les options suivantes sont disponibles :

    Pour installer le plug-in, procédez comme suit :

    1. Dans le tableau de bord Jenkins, accédez à Gérer Jenkins > Gérer les plug-ins.
    2. Sélectionnez Disponible et recherchez le plug-in de votre choix. La capture d'écran suivante montre le gestionnaire de plug-ins avec l'onglet Disponible.

      Gestionnaire de plug-ins Jenkins.

    3. Installez le plug-in.

Configurer Keycloak

Dans ce tutoriel, Keycloak gère les utilisateurs, les groupes et les rôles. Keycloak utilise des domaines pour gérer les utilisateurs.

  1. Sur la VM qui s'exécute en dehors de Google Cloud, installez le serveur Keycloak. Pour ce tutoriel, nous vous recommandons d'installer Keycloak à partir d'un conteneur Docker.

  2. Ouvrez la console d'administration Keycloak.

  3. Accédez aux paramètres du domaine.

  4. Dans l'onglet Général, vérifiez que les champs sont définis comme suit :

    • Activé : Activé
    • Accès géré par l'utilisateur : Désactivé
    • Points de terminaison : Configuration du point de terminaison OpenID et Métadonnées du fournisseur d'identité SAML 2.0

    La capture d'écran suivante montre les champs que vous devez configurer.

    Paramètres généraux de Keycloak.

  5. Créez un client afin de disposer d'une entité pouvant demander à Keycloak d'authentifier un utilisateur. Les clients sont souvent des applications et des services qui utilisent Keycloak pour fournir une solution d'authentification unique (SSO).

    1. Dans la console d'administration de Keycloak, cliquez sur Clients > Créer.
    2. Saisissez ce qui suit :

      • ID client : jenkins
      • Protocole client : openid-connect
      • URL racine : http://JENKINS_IP_ADDRESS:8080, où JENKINS_IP_ADDRESS est l'adresse IP de votre serveur Jenkins.

      La capture d'écran suivante montre les champs que vous devez configurer.

      Keycloak ajoute un client.

    3. Cliquez sur Enregistrer.

  6. Dans l'onglet Installation, vérifiez que le format du jeton est Keycloak OIDC JSON. Créez une copie de ce jeton, car vous en aurez besoin pour terminer la configuration de Jenkins.

  7. Pour créer un groupe de tests, procédez comme suit :

    1. Dans la console d'administration Keycloak, cliquez sur Groupes > Nouveau.
    2. Attribuez un nom à votre groupe, puis cliquez sur Enregistrer.
    3. Créez un autre groupe de test. Vous pouvez attribuer des rôles à vos groupes, mais ce tutoriel ne les requiert pas.
  8. Pour créer un utilisateur test à ajouter au groupe, procédez comme suit :

    1. Dans la console d'administration Keycloak, cliquez sur Gérer les utilisateurs > Ajouter des utilisateurs.
    2. Renseignez les informations sur l'utilisateur, puis cliquez sur Enregistrer.

      La capture d'écran suivante montre des exemples d'informations sur un compte utilisateur.

      Ajout d'un utilisateur à Keycloak.

    3. Cliquez sur l'onglet Identifiants et vérifiez que le paramètre Temporaire est Désactivé.

    4. Réinitialisez le mot de passe.

      Vous utiliserez ce compte ultérieurement dans le jeton JWT pour l'authentification.

      La capture d'écran suivante montre l'onglet Identifiants avec les champs à configurer.

      Keycloak modifie le mot de passe.

    5. Cliquez sur l'onglet Groupes et sélectionnez l'un des groupes que vous avez créés précédemment.

    6. Cliquez sur Participer.

    7. Répétez cette étape pour créer d'autres utilisateurs tests.

Configurer Jenkins pour OpenID Connect

Cette section explique comment configurer le plug-in OpenID Connect pour Jenkins.

  1. Sur votre serveur Jenkins, accédez à Gérer Jenkins > Configurer la sécurité globale.
  2. Sous "Domaine de sécurité", sélectionnez Plug-in d'authentification Keycloak. Cliquez sur Enregistrer.

  3. Cliquez sur Configurer le système.

  4. Sous les paramètres Global Keycloak, copiez le fichier JSON d'installation de Keycloak que vous avez créé à la section Configurer Keycloak. Si vous devez de nouveau obtenir les données JSON, procédez comme suit :

    1. Dans la console d'administration Keycloak, accédez à Clients.

    2. Cliquez sur le nom de votre client.

    3. Dans l'onglet Installation, cliquez sur Option de format et sélectionnez JSON OIDC Keycloak.

    Voici un exemple de fichier JSON Keycloak :

    {
        "realm":"master"
        "auth-server-url":"AUTHSERVERURL"
        "ssl-required":"none"
        "resource":"jenkins"
        "public-client":true
        "confidential-port":0
    }
    

    AUTHSERVERURL est l'URL de votre serveur d'authentification.

  5. Pour enregistrer la configuration OIDC, cliquez sur Enregistrer.

Jenkins peut désormais rediriger les utilisateurs vers Keycloak pour obtenir des informations sur les utilisateurs.

Installer les bibliothèques clientes Cloud

Pour envoyer un jeton JWT depuis Keycloak à Google Cloud, vous devez installer les bibliothèques clientes Cloud sur le serveur Jenkins. Ce tutoriel utilise Python pour interagir avec Google Cloud à l'aide du SDK.

  1. Installez Python sur le serveur Jenkins. Les étapes suivantes montrent comment installer Python3 :

    sudo apt update
    sudo apt install software-properties-common
    sudo add-apt-repository ppa:deadsnakes/ppa
    sudo apt update
    sudo apt install python3.8
    
  2. Installez pip3 pour pouvoir télécharger et importer les bibliothèques clientes Cloud :

    pip3 –version
    sudo apt update
    sudo apt install python3-pip
    pip3 –version
    
  3. Installez les bibliothèques clientes Cloud pour Python à l'aide de pip3 :

    pip3 install –upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
    

    Exemple :

    pip3 install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
    Collecting google-api-python-client
        Downloading google_api_python_client-2.42.0-py2.py3-none-any.whl (8.3 MB)
            USERNAME | 8.3 MB 19.9 MB/s
    Collecting google-auth-httplib2
        Downloading google_auth_httplib2-0.1.0-py2.py3-none-any.whl (9.3 MB)
    Collecting google-auth-oauthlib
    Downloading google_auth_oauthlib-0.5.1-py2.py3-non-any.whl (19 KB)
    

    Remplacez USERNAME par votre nom d'utilisateur.

  4. Installez Google Cloud CLI sur votre serveur Jenkins. Pour obtenir des instructions, consultez la page Démarrage rapide : installer gcloud CLI.

Configurer votre environnement Google Cloud

Cette section décrit les étapes à suivre pour vous assurer que votre environnement Google Cloud qui héberge votre conteneur sans serveur peut se connecter à Jenkins et Keycloak.

  1. Dans Google Cloud, créez un compte de service pour que le microservice sur Cloud Run puisse accéder aux autorisations qui y sont associées. Par exemple, pour créer un compte de service à l'aide de gcloud CLI, procédez comme suit :

    gcloud iam service-accounts create cloudrun-oidc \
      –-description="cloud run oidc sa"  \
      –-display-name="cloudrun-oidc"
    

    Par défaut, Cloud Run crée un compte de service par défaut. Cependant, l'utilisation du compte de service par défaut n'est pas une bonne pratique de sécurité, car le compte dispose d'un large ensemble d'autorisations. Par conséquent, nous vous recommandons de créer un compte de service distinct pour votre microservice. Pour savoir comment créer un compte de service pour Cloud Run, consultez la page Créer et gérer des comptes de service.

  2. Créez un pool de fédération d'identité de charge de travail. Pour créer un pool à l'aide de gcloud CLI, exécutez la commande suivante :

    gcloud iam workload-identity-pools create cloudrun-oidc-pool \
      --location="global" \
      —-description="cloudrun-oidc" \
      —-display-name="cloudrun-oidc"
    
  3. Créez un fournisseur de pools de fédération d'identité de charge de travail pour OpenID Connect :

    gcloud iam workload-identity-pools providers create-oidc cloud-run-provider \
      --workload-identity-pool="cloudrun-oidc-pool" \
      --issuer-uri="VAR_LINK_TO_ENDPOINT" \
      --location="global" \
      --attribute-mapping ="google.subject=assertion.sub,attribute.isadmin-assertion.isadmin,attribute.aud=assertion.aud" \
      --attribute-condition="attribute.isadmin=='true'"
    

    Remplacez VAR_LINK_TO_ENDPOINT par une variable contenant le lien vers le point de terminaison OIDC Keycloak. Pour trouver ce lien, accédez à la console d'administration KeyCloud dansDomaine cliquez sur l'icôneGénéral. Le point de terminaison doit être HTTPS, ce qui signifie que vous devez configurer votre serveur Keycloak avec HTTPS.

Obtenir le jeton JWT de l'utilisateur authentifié à partir de Keycloak

  1. Sur votre VM qui exécute Keycloak, téléchargez le jeton dans un fichier texte. Par exemple, sous Linux, exécutez la commande suivante :

    curl -L -X POST 'https://IP_FOR_KEYCLOAK:8080/auth/realms/master/protocol/openid-connect/token' -H 'Content-Type: application/x-www-form-urlencoded' \
      --data-urlencode 'client_id=jenks' \
      --data-urlencode 'grant_type=password' \
      --data-urlencode 'client_secret=CLIENT_SECRET \
      --data-urlencode 'scope=openid' \
      --data-urlencode 'username=USERNAME' \
      --data-urlencode 'password=PASSWORD' | grep access_token | cut -c18-1490 > token.txt
    

    Remplacez les éléments suivants :

    • IP_FOR_KEYCLOAK par l'adresse IP du serveur Keycloak.
    • CLIENT_SECRET par le code secret du client Keycloak.
    • USERNAME par un utilisateur de Keycloak.
    • PASSWORD par le mot de passe de l'utilisateur Keycloak.

    Cette commande inclut l'ID client, le code secret du client, le nom d'utilisateur et le mot de passe. Nous vous recommandons d'utiliser des variables d'environnement pour masquer ces valeurs plutôt que d'utiliser la ligne de commande. L'exemple de commande redirige les identifiants vers un fichier nommé token.txt.

    Vous pouvez également créer un script bash pour automatiser cette étape.

  2. Validez votre jeton sur jwt.io.

  3. Sur la VM, créez votre fichier d'identifiants :

    gcloud iam workload-identity-pools create-cred config \
    projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/cloudrun-oidc-pool/providers/cloud-run/provider \
      --output-file=sts-creds.json \
      --credential-source-file=token.txt
    

    Pour en savoir plus, consultez gcloud iam workload-identity-pools create-cred-config.

    Votre fichier de sortie devrait ressembler à ceci :

    {
        "type": "external_account",
        "audience": "//iam.google.apis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/cloudrun-oidc-pool/subject/USER_EMAIL",
        "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
        "token_url": "https://sts.googleapis.com/v1/token",
        "credential_source": {
            "file" "token.txt" }
    }
    

    PROJECT_NUMBER est le numéro de votre projet.

  4. Sur la VM, définissez le fichier sts.creds.json en tant que variable pour ADC :

    export GOOGLE_APPLICATION_CREDENTIALS=/Users/USERNAME/sts-creds.json
    

    Remplacez USERNAME par votre nom d'utilisateur UNIX.

    Avant le lancement de la fédération d'identité de charge de travail, cette valeur correspondait à la clé du compte de service. Avec la fédération d'identité de charge de travail, cette valeur correspond au fichier d'identifiants nouvellement créé.

  5. Créez une liaison de rôle pour que l'utilisateur emprunte l'identité du compte de service :

    gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT \
        --role roles/iam.workloadIdentityUser \
        --member "principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/cloudrun-oidc-pool/subject/USER_EMAIL
    

    Remplacez les éléments suivants :

  6. Autorisez le compte de service à accéder au service Cloud Run :

    gcloud run services add-iam-policy-binding SERVICE_NAME
      --member-"serviceAccount:SERVICE_ACCOUNT" \
      --role="roles/run.invoker"
    

    Remplacez les éléments suivants :

    • SERVICE_NAME par le nom du microservice exécuté sur Cloud Run.

    • SERVICE_ACCOUNT par l'adresse e-mail du compte de service pour Cloud Run.

    Pour en savoir plus, consultez la page gcloud run services add-iam-policy-binding.

  7. Générez un jeton d'ID :

    #!/usr/bin/python
    from google.auth import credentials
    from google.cloud import  iam_credentials_v1
    
    import google.auth
    import google.oauth2.credentials
    
    from google.auth.transport.requests import AuthorizedSession, Request
    
    url = "https://WORKLOAD_FQDN"
    aud = "https://WORKLOAD_FQDN"
    service_account = 'SERVICE_ACCOUNT'
    
    name = "projects/-/serviceAccounts/{}".format(service_account)
    id_token = client.generate_id_token(name=name,audience=aud, include_email=True)
    
    print(id_token.token)
    
    creds = google.oauth2.credentials.Credentials(id_token.token)
    authed_session = AuthorizedSession(creds)
    r = authed_session.get(url)
    print(r.status_code)
    print(r.text)
    

    Remplacez les éléments suivants :

    • WORKLOAD_FQDN par le nom de domaine complet de votre charge de travail.

    • SERVICE_ACCOUNT par l'adresse e-mail du compte de service pour Cloud Run.

Le jeton que vous utilisez peut appeler l'API Identity and Access Management, qui vous donnera le nouveau JWT dont vous avez besoin pour appeler votre service Cloud Run.

Vous pouvez utiliser votre jeton dans un pipeline Jenkins pour appeler le conteneur sans serveur que vous exécutez dans Cloud Run. Cependant, ces étapes n'entrent pas dans le cadre de ce tutoriel.

Effectuer un nettoyage

Pour éviter que les ressources utilisées lors de ce tutoriel ne soient facturées sur votre compte Google Cloud, vous pouvez supprimer le projet.

Supprimer le projet

  1. Dans la console Google Cloud, accédez à la page Gérer les ressources.

    Accéder à la page Gérer les ressources

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer.
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.

Étapes suivantes