Accéder aux ressources depuis un fournisseur d'identité OIDC

Ce document explique comment utiliser la fédération d'identité pour accéder aux ressources Google Cloud à partir d'un fournisseur d'identité compatible avec OpenID Connect (OIDC).

Traditionnellement, les applications exécutées en dehors de Google Cloud ont toujours utilisé des clés de compte de service pour accéder aux ressources Google Cloud. Grâce à la fédération d'identité, vous pouvez autoriser une identité externe à usurper l'identité d'un compte de service. Cela permet à votre charge de travail d'accéder directement aux ressources Google Cloud à l'aide d'un jeton d'accès de courte durée, et élimine les tâches de maintenance et de sécurité associées aux clés de compte de service.

Avant de commencer

  1. Activer les API IAM, Resource Manager, Service Account Credentials, and Security Token Service (STS).

    Activer les API

  2. Assurez-vous de disposer du rôle Administrateur de pools Workload Identity (roles/iam.workloadIdentityPoolAdmin).

    Le rôle de base IAM "Propriétaire" (roles/owner) inclut également des autorisations permettant de configurer la fédération d'identité. Les rôles de base ne doivent pas être attribués dans un environnement de production, mais ils peuvent être attribués dans un environnement de développement ou de test.

  3. Mettez à jour la règle d'administration de votre organisation pour autoriser la fédération du fournisseur d'identité.

  4. Créez un compte de service Google Cloud.

  5. Accordez l'accès au compte de service pour lui permettre d'appeler les API Google Cloud nécessaires à votre charge de travail.

Créer un pool d'identités de charge de travail

Un pool d'identités de charge de travail vous permet d'organiser et de gérer des identités externes. Les pools d'identités de charge de travail sont isolés les uns des autres, mais un pool peut usurper l'identité d'un nombre illimité de comptes de service. En général, nous vous recommandons de créer un pool pour chacun de vos environnements, par exemple pour vos environnements de développement, de préproduction ou de production.

Pour créer un pool d'identités de charge de travail, vous devez fournir un ID. Vous pouvez également fournir une description et un nom à afficher facultatifs.

gcloud

Exécutez la commande gcloud iam workload-identity-pools create pour créer un pool d'identités de charge de travail :

gcloud iam workload-identity-pools create pool-id \
    --location="global" \
    --description="description" \
    --display-name="display-name"

La réponse est semblable à ce qui suit :

Created workload identity pool [pool-id].

REST

La méthode projects.locations.workloadIdentityPools.create crée un pool d'identités de charge de travail.

Méthode HTTP et URL :

POST https://iam.googleapis.com/v1/projects/project-id/locations/global/workloadIdentityPools?workloadIdentityPoolId=pool-id

Corps JSON de la requête :

{
  "description": "description",
  "display-name": "display-name"
}

Pour envoyer votre requête, développez l'une des options suivantes :

La méthode renvoie un objet Operation de longue durée semblable à l'exemple suivant :

{
  "name": "projects/project-number/locations/global/workloadIdentityPools/pool-id/operations/operation-id"
}

Ajouter un fournisseur d'identité OIDC

Pour configurer un fournisseur d'identité OIDC pour votre pool d'identités de charge de travail, fournissez au minimum les informations suivantes :

  • Un ID pour le fournisseur.

  • L'ID du pool d'identités de la charge de travail de la section précédente de ce document.

  • L'URI d'émetteur du fournisseur. Cet URI se présente généralement sous la forme https://example.com. Pour trouver l'URI, consultez la documentation de votre fournisseur sur l'intégration OIDC.

  • Une liste de mappages d'attributs qui mappent les revendications d'un jeton externe aux attributs d'un jeton Google. Utilisez assertion pour faire référence aux identifiants externes, google pour les attributs Google et attribute pour les attributs personnalisés.

    Il existe deux attributs Google : google.subject et google.groups. Vous pouvez référencer ces attributs dans les liaisons de rôles IAM. google.subject s'affiche également dans les entrées de journal Cloud Logging.

    Vous devez fournir un mappage pour google.subject. En général, nous vous recommandons de mapper cet élément sur assertion.sub, ce qui devrait fournir un identifiant stable à utiliser dans les liaisons de rôles IAM. Voici un exemple de mappage :

    google.subject=assertion.sub
    

    Pour les assertions plus complexes, vous pouvez utiliser Common Expression Language. Par exemple, si votre pool d'identités de charge de travail contient plusieurs fournisseurs d'identité, vous pouvez ajouter un préfixe pour lever toute ambiguïté :

    google.subject="provider-a::" + assertion.sub
    

    Le champ google.subject ne peut pas dépasser 127 caractères.

    Vous pouvez également spécifier des attributs personnalisés. Par exemple, les éléments suivants mappent assertion.foo sur attribute.bar :

    attribute.bar=assertion.foo
    

    Consultez la documentation de votre fournisseur sur les jetons d'accès pour obtenir la liste complète des revendications auxquelles vous pouvez faire référence.

    Pour référencer une partie spécifique d'une revendication dans une expression, utilisez la fonction CEL extract(), qui extrait une valeur d'une revendication en suivant un modèle que vous fournissez. Pour en savoir plus sur extract(), consultez Extraire des valeurs à partir d'attributs.

    Pour vérifier si un identifiant contient une revendication, utilisez la fonction has().

  • Liste d'audiences autorisées spécifiant les valeurs que le champ aud de l'identifiant externe peut contenir. Vous pouvez configurer jusqu'à de 10 audiences, chacune comptant 256 caractères maximum. Consultez la documentation de votre fournisseur pour en savoir plus sur les valeurs par défaut de aud.

    Si votre fournisseur d'identité vous permet de configurer une valeur personnalisée pour aud, vous pouvez laisser le paramètre des audiences autorisées vide et définir la valeur de aud sur le nom complet de la ressource de votre fournisseur d'identité de charge de travail. Le préfixe HTTP est facultatif. Par exemple :

    //iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/providers/provider-id
    https://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/providers/provider-id
    

    Dans les deux cas, toutes les requêtes d'échange de jetons qui ne contiennent pas l'une des valeurs autorisées sont rejetées.

Vous pouvez également fournir plusieurs paramètres facultatifs :

  • Un nom à afficher et une description.

  • Une condition spécifiant les attributs que le compte principal doit présenter. La condition peut s'appliquer aux revendications des identifiants externe ou aux attributs de l'identifiant Google. Toute requête qui ne répond pas à la condition est rejetée.

    Les conditions possèdent le format d'une expression CEL qui renvoie une valeur booléenne. Par exemple, la requête suivante rejette les requêtes des identités qui ne sont pas membres d'un groupe spécifique :

    group in assertion.groups
    

    Si le fournisseur d'identité est disponible pour le grand public, l'utilisation de conditions est fortement recommandée. Pour en savoir plus sur les cas d'utilisation courants des conditions, consultez la page de présentation de la fédération d'identité de charge de travail.

L'exemple suivant montre comment ajouter un fournisseur d'identité :

gcloud

Exécutez la commande gcloud iam workload-identity-pools providers create-oidc pour ajouter un fournisseur d'identité :

gcloud iam workload-identity-pools providers create-oidc provider-id \
    --workload-identity-pool="pool-id" \
    --issuer-uri="issuer-uri" \
    --location="global" \
    --attribute-mapping="google.subject=assertion.sub"

La réponse est semblable à ce qui suit :

Created workload identity pool provider [provider-id].

REST

La méthode projects.locations.workloadIdentityPools.providers.create ajoute un fournisseur d'identité OIDC.

Méthode HTTP et URL :

POST https://iam.googleapis.com/v1/projects/project-id/locations/global/workloadIdentityPools/pool-id/providers?workloadIdentityPoolProviderId=provider-id

Corps JSON de la requête :

{
  "issuerUrl": "issuer-uri"
}

Pour envoyer votre requête, développez l'une des options suivantes :

La méthode renvoie un objet Operation de longue durée semblable à l'exemple suivant :

{
  "name": "projects/project-number/locations/global/workloadIdentityPools/pool-id/providers/provider-id/operations/operation-id"
}

Accorder une autorisation pour emprunter l'identité d'un compte de service

Les identités externes ne peuvent pas accéder directement à la plupart des ressources Google Cloud. Pour permettre à ces identités d'emprunter l'identité d'un compte de service, vous devez leur attribuer le rôle Utilisateur Workload Identity (roles/iam.workloadIdentityUser).

Pour ajouter cette liaison de rôle à une identité spécifique, utilisez la valeur que vous avez mappée sur google.subject :

gcloud iam service-accounts add-iam-policy-binding service-account-email \
    --role roles/iam.workloadIdentityUser \
    --member "principal://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/subject/subject"

Pour ajouter cette liaison pour tous les membres d'un groupe :

gcloud iam service-accounts add-iam-policy-binding service-account-email \
    --role roles/iam.workloadIdentityUser \
    --member "principalSet://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/group/group-name"

Vous pouvez également accorder l'accès en fonction d'attributs personnalisés. Exemple :

gcloud iam service-accounts add-iam-policy-binding service-account-email \
    --role="roles/iam.workloadIdentityUser" \
    --member="principalSet://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/attribute.custom-attribute-name/custom-attribute-value"

Pour révoquer l'accès, remplacez add-iam-policy-binding par remove-iam-policy-binding.

Vous pouvez également ajouter ou révoquer des liaisons à l'aide de l'API REST ou des bibliothèques clientes. Pour en savoir plus, consultez Accorder, modifier et révoquer les accès à des ressources.

Générer des identifiants Google

Si vous utilisez une bibliothèque cliente compatible, vous pouvez la configurer de sorte qu'elle génère automatiquement des identifiants Google. Vous pouvez également générer manuellement un jeton d'ID OIDC, puis l'échanger contre des identifiants Google.

Lorsque cela est possible, nous vous recommandons de générer automatiquement les identifiants afin de ne pas avoir à mettre en œuvre vous-même le processus d'échange de jetons.

Générer automatiquement des identifiants

Si vous accédez à Google Cloud à l'aide d'une bibliothèque cliente pour l'un des langages suivants, vous pouvez configurer la bibliothèque cliente pour qu'elle génère automatiquement les identifiants à l'aide de la fédération d'identité :

C++

La plupart des bibliothèques clientes Google Cloud pour C++ sont compatibles avec la fédération d'identité à l'aide d'un objet ChannelCredentials, créé en appelant grpc::GoogleDefaultCredentials(). Pour initialiser cet identifiant, vous devez créer les bibliothèques clientes avec la version 1.36.0 ou ultérieure de gRPC.

La bibliothèque cliente Cloud Storage pour C++ utilise l'API REST et non gRPC. Elle n'est donc pas compatible avec la fédération d'identités.

Go

Les bibliothèques clientes pour Go sont compatibles avec la fédération d'identité si elles utilisent la version 0.0.0-20210218202405-ba52d332ba99 ou une version ultérieure du module golang.org/x/oauth2.

Pour vérifier quelle version de ce module est utilisée par votre bibliothèque cliente, exécutez les commandes suivantes :

cd $GOPATH/src/cloud.google.com/go
go list -m golang.org/x/oauth2

Java

Les bibliothèques clientes pour Java sont compatibles avec la fédération d'identité si elles utilisent la version 0.24.0 ou une version ultérieure de l'artefact com.google.auth:google-auth-library-oauth2-http.

Pour vérifier la version de cet artefact utilisée par votre bibliothèque cliente, exécutez la commande Maven suivante dans le répertoire de votre application :

mvn dependency:list -DincludeArtifactIds=google-auth-library-oauth2-http

Node.js

Les bibliothèques clientes pour Node.js sont compatibles avec la fédération d'identité si elles utilisent la version 7.0.2 ou ultérieure du package google-auth-library.

Pour vérifier la version de ce package utilisée par votre bibliothèque cliente, exécutez la commande suivante dans le répertoire de votre application :

npm list google-auth-library

Lorsque vous créez un objet GoogleAuth, vous pouvez spécifier un ID de projet ou autoriser GoogleAuth à le trouver automatiquement. Pour trouver automatiquement l'ID du projet, le compte de service dans le fichier de configuration doit disposer du rôle de visiteur (roles/browser) ou d'un rôle avec des autorisations équivalentes sur votre projet. Pour en savoir plus, consultez la section README du package google-auth-library.

Python

Les bibliothèques clientes pour Python sont compatibles avec la fédération d'identité si elles utilisent la version 1.27.0 ou ultérieure du package google-auth.

Pour vérifier la version de ce package utilisée par votre bibliothèque cliente, exécutez la commande suivante dans l'environnement dans lequel le package est installé :

pip show google-auth

Pour spécifier un ID de projet pour le client d'authentification, vous pouvez définir la variable d'environnement GOOGLE_CLOUD_PROJECT ou autoriser le client à trouver automatiquement l'ID du projet. Pour trouver automatiquement l'ID du projet, le compte de service dans le fichier de configuration doit disposer du rôle de visiteur (roles/browser) ou d'un rôle avec des autorisations équivalentes sur votre projet. Pour en savoir plus, consultez le guide de l'utilisateur du package google-auth.

La bibliothèque cliente peut obtenir des jetons du fournisseur d'identité de différentes manières :

  • Identifiants basés sur un fichier : les jetons sont chargés à partir d'un fichier. Un autre processus doit actualiser ce fichier avec un nouveau jeton OIDC avant l'expiration de l'ancien. Par exemple, si le jeton a une durée de vie d'une heure, vous devez actualiser le fichier avant qu'il soit obsolète.
  • Identifiants basés sur une URL : les jetons sont chargés à partir d'un serveur local avec un point de terminaison qui répond aux requêtes HTTP GET. La réponse doit être un jeton d'identification OIDC, au format texte brut ou au format JSON.

Pour utiliser les identifiants provenant du fichier, exécutez la commande gcloud iam workload-identity-pools create-cred-config pour générer le fichier de configuration. L'option --credential-source-type est facultative. L'option --credential-source-field-name l'est également, sauf si --credential-source-type est défini sur json :

gcloud iam workload-identity-pools create-cred-config \
    projects/project-number/locations/global/workloadIdentityPools/pool-id/providers/provider-id \
    --service-account=service-account-email \
    --output-file=configuration-filepath \
    --credential-source-file=token-filepath \
    --credential-source-type=source-type \
    --credential-source-field-name=field-name

Remplacez les valeurs suivantes :

  • project-number : ID numérique du projet.
  • pool-id : ID du pool d'identités de charge de travail.
  • provider-id : ID du fournisseur de pools d'identités de charge de travail.
  • service-account-email : adresse e-mail du compte de service dont l'identité doit être empruntée.
  • configuration-filepath : chemin d'accès du fichier de configuration.
  • token-filepath : chemin d'accès au fichier où les jetons d'identification OIDC seront stockés.
  • source-type : format du fichier de jeton d'ID OIDC. Définissez-la sur text ou json. La valeur par défaut est text.
  • field-name : pour les fichiers de jeton JSON, nom du champ JSON contenant le jeton. Obligatoire si la valeur de --credential-source-type est json.

Pour utiliser les identifiants provenant d'une URL, exécutez la commande gcloud iam workload-identity-pools create-cred-config pour générer le fichier de configuration. Les options --credential-source-headers et --credential-source-type sont facultatives. L'option --credential-source-field-name l'est également, sauf si --credential-source-type est défini sur json :

gcloud iam workload-identity-pools create-cred-config \
    projects/project-number/locations/global/workloadIdentityPools/pool-id/providers/provider-id \
    --service-account=service-account-email \
    --output-file=configuration-filepath \
    --credential-source-url="token-url" \
    --credential-source-headers="key1=value1,key2=value2" \
    --credential-source-type=source-type \
    --credential-source-field-name=field-name

Remplacez les valeurs suivantes :

  • project-number : ID numérique du projet.
  • pool-id : ID du pool d'identités de charge de travail.
  • provider-id : ID du fournisseur de pools d'identités de charge de travail.
  • service-account-email : adresse e-mail du compte de service dont l'identité doit être empruntée.
  • configuration-filepath : chemin d'accès du fichier de configuration.
  • token-url : URL qui fournit des jetons d'identification OIDC en réponse aux requêtes HTTP GET.
  • key1, key2 : nom d'un en-tête HTTP à inclure dans la requête.
  • value1, value2 : valeur d'un en-tête HTTP à inclure dans la requête.
  • source-type : format du fichier de jeton OIDC. Définissez-le sur text ou json. La valeur par défaut est text.
  • field-name : pour les fichiers de jeton JSON, nom du champ contenant le jeton. Obligatoire si la valeur de --credential-source-type est json.

Après avoir généré le fichier de configuration, définissez la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS sur le chemin d'accès du fichier de configuration. Cette variable d'environnement indique à la bibliothèque cliente d'utiliser les identifiants par défaut de l'application pour s'authentifier. Pour en savoir plus, consultez la section Rechercher automatiquement des identifiants.

Échanger manuellement des identifiants

Une fois que votre identité externe est capable d'usurper l'identité d'un compte de service, vous pouvez échanger ses identifiants manuellement pour des identifiants Google.

Pour échanger des identifiants, procédez comme suit :

  1. Obtenez un jeton d'identification OIDC auprès de votre fournisseur d'identité (consultez la documentation de votre fournisseur pour obtenir des instructions détaillées).

  2. Transmettez le jeton d'identification OIDC au service de jetons de sécurité token() afin d'obtenir un jeton d'accès fédéré :

    REST

    La méthode token échange un jeton tiers contre un jeton Google.

    Avant d'utiliser les données de requête ci-dessous, effectuez les remplacements suivants :

    • project-number : numéro de votre projet Google Cloud.
    • pool-id : ID du pool d'identités de charge de travail que vous avez créé précédemment dans ce tutoriel.
    • provider-id : ID du fournisseur d'identité que vous avez configuré précédemment dans ce tutoriel.

    Méthode HTTP et URL :

    POST https://sts.googleapis.com/v1/token

    Corps JSON de la requête :

    {
      "audience": "//iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/providers/provider-id",
      "grantType": "urn:ietf:params:oauth:grant-type:token-exchange",
      "requestedTokenType": "urn:ietf:params:oauth:token-type:access_token",
      "scope": "https://www.googleapis.com/auth/cloud-platform",
      "subjectTokenType": "urn:ietf:params:oauth:token-type:jwt",
      "subjectToken": "oidc-id-token"
    }
    

    Pour envoyer votre requête, développez l'une des options suivantes :

     

    La méthode renvoie un jeton fédéré.

  3. Appelez generateAccessToken() pour échanger le jeton fédéré contre un jeton d'accès au compte de service. Un nombre limité d'API Google Cloud acceptent les jetons fédérés. Toutes les API Google Cloud sont compatibles avec les jetons d'accès au compte de service.

    REST

    La méthode serviceAccounts.generateAccessToken de l'API Service Account Credentials génère un jeton d'accès OAuth 2.0 pour un compte de service.

    Avant d'utiliser les données de requête ci-dessous, effectuez les remplacements suivants :

    • PROJECT_ID : ID de votre projet Google Cloud. Les ID de projet sont des chaînes alphanumériques, telles que my-project.
    • SA_ID : ID de votre compte de service. Il peut s'agir de l'adresse e-mail du compte de service au format SA_NAME@PROJECT_ID.iam.gserviceaccount.com ou de l'ID numérique unique du compte de service.
    • token : jeton d'accès fédéré.

    Méthode HTTP et URL :

    POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SA_NAME@PROJECT_ID.iam.gserviceaccount.com:generateAccessToken

    Corps JSON de la requête :

    {
      "scope": [
        "https://www.googleapis.com/auth/cloud-platform"
      ]
    }
    

    Pour envoyer votre requête, développez l'une des options suivantes :

    Si la requête generateAccessToken a abouti, le corps de la réponse contient un jeton d'accès OAuth 2.0 et une heure d'expiration. Ce jeton d'accès (accessToken) peut alors être utilisé pour authentifier une requête au nom du compte de service jusqu'à ce que l'heure d'expiration spécifiée expireTime soit atteinte :

    {
      "accessToken": "eyJ0eXAi...NiJ9",
      "expireTime": "2020-04-07T15:01:23.045123456Z"
    }
    

Une fois que vous disposez d'un jeton d'accès pour un compte de service, vous pouvez l'utiliser pour appeler les API Google Cloud en l'incluant dans l'en-tête Authorization de vos requêtes :

Authorization: Bearer service-account-access-token

La requête est autorisée en tant que compte de service.

Étape suivante