Ce document explique comment configurer l'accès basé sur les certificats pour la fédération d'identité de charge de travail à l'aide de certificats X.509.
L'accès basé sur les certificats utilise le protocole TLS mutuel (mTLS) pour authentifier le client et le serveur lors d'un handshake TLS. Dans ce processus, une liaison mTLS intègre des règles basées sur le contexte de transport et utilise l'état du certificat du client dans la session TLS pour prendre des décisions d'autorisation.
Pour la fédération d'identité de charge de travail X.509, une liaison mTLS garantit que l'ensemble du flux d'authentification est associé de manière sécurisée à une charge de travail de confiance. Cela atténue le risque de vol d'identifiants, car l'authentification est liée à un point de terminaison spécifique et fiable.
Présentation de la configuration de l'accès basé sur les certificats pour la fédération d'identité de charge de travail
Vous trouverez ci-dessous un aperçu général du processus de configuration de l'accès basé sur les certificats pour la fédération d'identité de charge de travail :
Établissez une fédération d'identité de charge de travail en configurant la confiance avec l'ancrage de confiance des certificats X.509.
Créez un niveau d'accès pour l'accès basé sur des certificats.
Ajoutez le niveau d'accès à une règle d'accès contextuel qui applique la liaison mTLS.
Avant de commencer
Vérifiez que vous remplissez les conditions préalables suivantes :
La dernière version de Google Cloud CLI
Pour passer à la dernière version de Google Cloud CLI, exécutez la commande suivante :
gcloud components update
Si vous devez installer Google Cloud CLI, consultez Installer Google Cloud CLI.
Une configuration de la fédération d'identité de charge de travail qui utilise votre point d'ancrage de confiance des certificats X.509
Pour utiliser cette fonctionnalité, remplissez le formulaire suivant afin d'être ajouté à une liste d'autorisation : Formulaire de demande d'ajout à la liste d'autorisation. Vous serez contacté une fois que vous aurez été ajouté à la liste d'autorisation.
Créer un niveau d'accès pour les certificats
Créez un niveau d'accès mTLS. Le niveau d'accès mTLS valide les certificats lorsqu'il détermine l'accès aux ressources.
Console
Dans Access Context Manager, créez un niveau d'accès personnalisé et saisissez l'expression suivante dans le champ d'expression CEL :
request.auth.matchesMtlsTokens(origin) == true
.gcloud
Pour créer un niveau d'accès personnalisé, exécutez la commande suivante :
gcloud access-context-manager levels create ACCESS_LEVEL_NAME
--title=TITLE
--custom-level-spec=FILE
--description=DESCRIPTION
--policy=POLICY_NAMERemplacez les éléments suivants :
ACCESS_LEVEL_NAME
: nom du niveau d'accès.TITLE
: titre du niveau d'accès.FILE
: fichier YAML avec le contenu suivant :request.auth.matchesMtlsTokens(origin) == true
.DESCRIPTION
: description du niveau d'accès.POLICY_NAME
: nom de la règle d'accès.
Exportez le niveau d'accès que vous avez créé vers une variable d'environnement. Cette variable est utilisée dans les étapes suivantes.
export ACCESS_LEVEL_ID=ACCESS_LEVEL_ID
Remplacez
ACCESS_LEVEL_ID
par le nom du niveau d'accès, par exempleaccessPolicies/12345/accessLevels/acl_1
.
Créer une association d'accès contextuel pour un pool d'identités de charge de travail
Définissez les variables d'environnement suivantes.
export ORG_ID=ORG_ID export CALLER_PROJECT_ID=CALLER_PROJECT_ID export FEDERATED_PRINCIPAL=FEDERATED_PRINCIPAL
Remplacez les éléments suivants :
ORG_ID
: ID de votre organisation.CALLER_PROJECT_ID
: ID du projet à utiliser pour appeler les API.FEDERATED_PRINCIPAL
: nom du compte principal d'identité dans le pool d'identités de charge de travail qui respecte la règle d'accès contextuel. Vous pouvez utiliser l'une des options suivantes :une identité unique au format :
principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/SUBJECT_ATTRIBUTE_VALUE
OU
Toutes les identités d'un pool au format :
principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/*
gcloud
gcloud alpha access-context-manager cloud-bindings create \ --organization=
ORG_ID
\ --federated-principal=FEDERATED_PRINCIPAL
\ --level=ACCESS_LEVEL_ID
--dry-run-level=DRY_RUN_ACCESS_LEVEL_ID
Remplacez les éléments suivants :
ACCESS_LEVEL_ID
: nom du niveau d'accès.DRY_RUN_ACCESS_LEVEL_ID
: nom du niveau d'accès en mode simulation. Nous vous recommandons d'activer d'abord une liaison de règle en mode simulation pour comprendre l'impact potentiel sur le trafic existant.
curl
Créez un fichier JSON avec la liaison d'accès contextuel.
Vous ne pouvez fournir qu'un seul niveau d'accès dans une demande, même si le champ est répété. Vous pouvez utiliser les types de principaux fédérés suivants :
- Identité unique :
principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/SUBJECT_ATTRIBUTE_VALUE
- Toutes les identités d'un pool :
principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/*
echo { \ \"principal\": { \ \"federatedPrincipal\": \"${FEDERATED_PRINCIPAL:?}\" \ },\ \"accessLevels\": [\"${ACCESS_LEVEL_ID:?}\"] \ } \ >> request.json
- Identité unique :
Utilisez
curl
pour envoyer la requête HTTP suivante.curl -H "X-Goog-User-Project: ${CALLER_PROJECT_ID:?}" -X POST \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json; charset=utf-8" \ -d @request.json \ "https://accesscontextmanager.googleapis.com/v1alpha/organizations/${ORG_ID:?}/gcpUserAccessBindings"
Autoriser l'accès à l'aide des bibliothèques clientes Google Cloud
Pour autoriser les charges de travail de la fédération d'identité de personnel à l'aide des bibliothèques clientesGoogle Cloud , procédez comme suit.
Créez un fichier ADC (Identifiants par défaut de l'application) configuré pour l'authentification Workforce Identity Federation.
gcloud iam workload-identity-pools create-cred-config IDENTITY_POOL_ID \ --credential-cert-path WORKLOAD_CERTIFICATE_PATH \ --credential-cert-private-key-path WORKLOAD_KEY_PATH \ --output-file ADC_FILE_OUTPUT_PATH
Remplacez les éléments suivants :
IDENTITY_POOL_ID
: ID de votre pool d'identités de charge de travail.WORKLOAD_CERTIFICATE_PATH
: chemin d'accès au fichier de certificat de votre charge de travail.WORKLOAD_KEY_PATH
: chemin d'accès au fichier de clé privée de votre charge de travail.ADC_FILE_OUTPUT_PATH
: chemin d'accès au fichier ADC.
Cette commande génère également un fichier de configuration de certificat dans le répertoire de configuration par défaut de votre gcloud CLI. Le fichier de configuration du certificat permet l'authentification initiale et établit des handshakes mTLS pour les requêtes ultérieures envoyées aux ressources Google Cloud .
Définissez une variable d'environnement pour qu'elle pointe vers le fichier ADC. Vos identifiants seront alors détectables par les bibliothèques clientes Google.
export GOOGLE_APPLICATION_CREDENTIALS=${application_default_credentials.json}
Cette étape est facultative si vous omettez l'argument
--output-file
lorsque vous générez le fichier ADC. Si vous omettez l'argument, le fichier ADC est créé et lu à partir de votre répertoire de configuration par défaut gcloud CLI.Cette fonctionnalité est compatible avec les bibliothèques clientes en Go, Python et Java. Vous devez définir la variable d'environnement pour activer mTLS pour Python et Java.
Pour établir et tester rapidement l'accès mTLS aux API Google Cloud , vous pouvez utiliser les exemples de code suivants.
Go
Utilisez l'exemple suivant pour créer un fichier Go, tel que
golang_test.go
.package golang_test import ( "io" "log" "testing" "cloud.google.com/go/auth/credentials" "cloud.google.com/go/auth/httptransport" ) func TestGoExample(t *testing.T) { scopes := []string{ "https://www.googleapis.com/auth/pubsub", // Scope for Pub/Sub access // Add other scopes as needed } dopts := credentials.DetectOptions{ Scopes: scopes, } // Create httptransport.Options with the scopes opts := &httptransport.Options{ DetectOpts: &dopts, } hc, err := httptransport.NewClient(opts) if err != nil { t.Fatalf("NewHTTPClient: %v", err) } resp, err := hc.Get("https://pubsub.mtls.googleapis.com/v1/projects/PROJECT_ID/topics") if err != nil { t.Fatalf("Get: %v", err) } t.Logf("Status: %s", resp.Status) t.Cleanup(func() { resp.Body.Close() }) b, err := io.ReadAll(resp.Body) if err != nil { t.Fatal(err) } log.Println(string(b)) }
Remplacez PROJECT_ID par l'ID de votre projet gcloud CLI.
Pour exécuter un test sur une VM Compute Engine, utilisez la commande suivante.
go mod init example.com go mod tidy go test -v golang_test.go --count=1
Python
Utilisez l'exemple suivant pour créer un fichier de test, tel que
python_test.py
.import google.auth import google.auth.transport.requests import requests def test_go_example(): # Define the required scopes for your application scopes = [ "https://www.googleapis.com/auth/pubsub", # Scope for Pub/Sub access # Add other scopes as needed ] # Obtain Application Default Credentials (ADC) with the specified scopes credentials, _ = google.auth.default(scopes=scopes) # Create an authorized HTTP session using the ADC credentials authed_session = google.auth.transport.requests.AuthorizedSession(credentials) try: # Make a GET request to the Pub/Sub API endpoint response = authed_session.get( "https://pubsub.mtls.googleapis.com/v1/projects/PROJECT_ID/topics" ) # Check if the request was successful response.raise_for_status() # Raise an exception for error statuses # Log the response status and content print(f"Status: {response.status_code}") print(response.text) except requests.exceptions.RequestException as e: print(f"Error making the request: {e}") if __name__ == "__main__": test_go_example()
Remplacez PROJECT_ID par l'ID de votre projet gcloud CLI.
Pour exécuter un test sur une VM Compute Engine, procédez comme suit.
- Configurez un environnement virtuel Python.
Installez les bibliothèques requises.
pip install google-auth google-auth-httplib2 requests
Exécutez le test :
python3 python_test.py
Autoriser l'utilisation de requêtes HTTP simples
Pour autoriser les charges de travail de la fédération d'identité de personnel à l'aide de requêtes HTTP simples, procédez comme suit.
Obtenez un jeton d'accès lié à un certificat à partir du service de jetons de sécurité Google Cloud via une négociation mTLS standard.
Appelez les services Google Cloud avec le jeton d'accès que vous avez obtenu auprès du service de jetons de sécurité. Cet exemple interroge Cloud Storage.
$ curl --key ${workload_key.pem} --cert ${workload_cert.pem} -X GET 'https://storage.mtls.googleapis.com/{replace_with_your_resources}' -H "Authorization: Bearer $ACCESS_TOKEN"
La liaison mTLS impose l'utilisation de mTLS. Exécutez la commande suivante pour vérifier qu'une connexion non mTLS échoue avec une erreur d'autorisation.
$ curl -X GET 'https://storage.googleapis.com/{replace_with_your_resources}' -H "Authorization: Bearer $ACCESS_TOKEN"
Lister la liaison de stratégie
Pour lister l'association de stratégie pour la fédération d'identité de charge de travail, exécutez la commande suivante.
gcloud
La commande suivante liste les liaisons spécifiques au sein d'une organisation donnée, en filtrant celles qui s'appliquent aux comptes principaux fédérés.
gcloud alpha access-context-manager cloud-bindings list \
--organization=ORG_ID
\
--filter='principal:federatedPrincipal'
curl
curl -H "X-Goog-User-Project: ${CALLER_PROJECT_ID:?}" -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://accesscontextmanager.googleapis.com/v1alpha/organizations/${ORG_ID:?}/gcpUserAccessBindings?filter=principal%3Afederated_principal"
Mettre à jour une association de règle
Pour mettre à jour une liaison de stratégie, ajoutez le nouveau niveau d'accès à un fichier JSON et exécutez la commande suivante.
gcloud
gcloud alpha access-context-manager cloud-bindings update \ --binding=BINDING_ID
\ --level=NEW_ACCESS_LEVEL_ID
curl
curl -H "X-Goog-User-Project: ${CALLER_PROJECT_ID:?}" -X PATCH \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://accesscontextmanager.googleapis.com/v1alpha/organizations/${ORG_ID:?}/gcpUserAccessBindings/${BINDING_ID:?}?updateMask=access_levels"
Supprimer une liaison de stratégie
Pour supprimer une association de règle, exécutez la commande suivante.
gcloud
gcloud alpha access-context-manager cloud-bindings delete \
--binding=BINDING_ID
curl
curl -H "X-Goog-User-Project: ${CALLER_PROJECT_ID:?}" -X DELETE \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://accesscontextmanager.googleapis.com/v1alpha/organizations/${ORG_ID:?}/gcpUserAccessBindings/${BINDING_ID:?}"
Dépannage
Voici quelques problèmes courants et les actions suggérées pour les résoudre :
Erreur :
403 Forbidden, user does not have permission.
Action : Vérifiez la stratégie IAM pour vous assurer que le pool d'identités de charge de travail a accès à votre ressource Google Cloud .
Erreur :
Unauthorized_client: Could not obtain a value for google.subject from the given credential.
Action : le backend n'a pas pu extraire de valeur pour
google.subject
à partir de votre certificat client en fonction du mappage des attributs. Vérifiez votre certificat client pour vous assurer que le champ que vous utilisez pour le mappage a une valeur.Si vous rencontrez des refus d'accès inattendus après avoir activé l'accès contextuel, vous pouvez rapidement débloquer le trafic en supprimant l'association de l'accès contextuel à l'aide de la commande suivante :
gcloud alpha access-context-manager cloud-bindings delete
Une fois l'accès rétabli, consultez le journal d'audit pour déterminer pourquoi les demandes ont été refusées.