S'authentifier auprès de services externes à l'aide de la propre identité d'un agent

Les agents hébergés sur Google Cloud peuvent utiliser leur propre identité pour s'authentifier auprès des outils et services hébergés sur les runtimes Google Cloud , tels que Cloud Run ou Google Kubernetes Engine (GKE), en demandant un jeton d'ID OpenID Connect (OIDC) à l'identité de l'agent. Les agents peuvent également utiliser ces jetons d'identité pour s'authentifier auprès de plates-formes cloud tierces (telles qu'Amazon Web Services (AWS) et Microsoft Azure), d'API personnalisées, de passerelles d'API et de backends sur site.

Lorsqu'un agent agit de sa propre autorité pour accéder à un service externe, Agent Identity émet un jeton d'identification OpenID Connect (OIDC). Ce jeton Web JSON (JWT) affirme l'identité SPIFFE de l'agent et est signé par les clés de l'émetteur pour le domaine de confiance de l'agent (pool d'identités de charge de travail géré). Les systèmes externes peuvent valider ces jetons sans Google Cloud identifiants ni SDK via des points de terminaison publics hébergés par le Google Cloud service de jetons de sécurité :

  • Un point de terminaison OpenID Connect Discovery 1.0 (/.well-known/openid-configuration) qui publie les métadonnées du fournisseur OpenID et le point de terminaison de clé publique (jwks_uri).
  • Un point de terminaison JWKS (JSON Web Key Set) (/openid/jwks) qui fournit les clés publiques actives utilisées pour valider les signatures sur les jetons d'ID d'agent.

Avant de commencer

  1. Vérifiez que vous avez choisi la bonne méthode d'authentification. Découvrez comment fonctionnent les identités SPIFFE et les domaines de confiance, ainsi que les identifiants d'agent dans la présentation d'Agent Identity.
  2. Créez et déployez un agent avec l'identité de l'agent activée.
  3. Assurez-vous que votre service externe ou fournisseur d'identité répond aux exigences suivantes :
  4. Identifiez les valeurs de configuration suivantes pour votre agent et votre service externe cible :
    • URL de l'émetteur (revendication iss) : URL de l'émetteur du pool d'identités de charge de travail pour votre organisation (https://sts.googleapis.com/v1/organizations/ORGANIZATION_ID/locations/global/workloadIdentityPools/TRUST_DOMAIN) ou votre projet (https://sts.googleapis.com/v1/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/TRUST_DOMAIN).
    • Audience autorisée (revendication aud) : URI d'audience attendu par le fournisseur d'identité ou le service externe lors de la validation des jetons d'identité.
  5. Vérifiez que vous disposez des rôles requis pour effectuer cette tâche.

Rôles requis

Pour obtenir les autorisations nécessaires pour déployer un agent avec l'identité de l'agent, demandez à votre administrateur de vous accorder les rôles IAM suivants sur votre projet :

Pour en savoir plus sur l'attribution de rôles, consultez Gérer l'accès aux projets, aux dossiers et aux organisations.

Ces rôles prédéfinis contiennent les autorisations requises pour déployer un agent avec l'identité de l'agent. Pour connaître les autorisations exactes requises, développez la section Autorisations requises :

Autorisations requises

Les autorisations suivantes sont requises pour déployer un agent avec l'identité de l'agent :

  • Déployez un agent sur Agent Runtime sur Gemini Enterprise Agent Platform :
    • aiplatform.reasoningEngines.create
    • aiplatform.reasoningEngines.update
  • Déployez un service d'agent sur Cloud Run :
    • run.services.create
    • run.services.update

Vous pouvez également obtenir ces autorisations avec des rôles personnalisés ou d'autres rôles prédéfinis.

Obtenir un jeton d'ID OIDC pour un agent

Pour configurer votre agent afin qu'il obtienne et envoie un jeton d'ID OIDC à un service externe, procédez comme suit :

  1. Configurer votre agent avec l'identité de l'agent
  2. Demander un jeton d'ID OIDC dans le code de l'application

Configurer votre agent avec l'identité de l'agent

Activez l'identité de l'agent lorsque vous déployez votre agent :

  • Si vous déployez votre agent sur Agent Runtime sur Gemini Enterprise Agent Platform , définissez identity_type sur AGENT_IDENTITY :

    remote_app = client.agent_engines.create(
        agent=app,
        config={
            "identity_type": types.IdentityType.AGENT_IDENTITY,
            "requirements": ["google-cloud-aiplatform[agent_engines,adk]"],
        },
    )
    
  • Si vous déployez un service d'agent conteneurisé sur Cloud Run, transmettez l'indicateur --identity-type=agent-identity :

    gcloud run deploy SERVICE_NAME \
        --image=IMAGE_URL \
        --identity-type=agent-identity \
        --no-allow-unauthenticated

    Remplacez les éléments suivants :

    • SERVICE_NAME : nom de votre service Cloud Run.
    • IMAGE_URL : URL de l'image de conteneur de votre agent.

Demander un jeton d'ID OIDC dans le code de l'application

Dans le code d'application de votre agent, utilisez la bibliothèque cliente Google Auth pour demander un jeton d'identité OIDC pour votre audience externe cible. La bibliothèque cliente gère la génération de jetons, la mise en cache locale et le renouvellement automatique à partir du serveur de métadonnées.

Par défaut, les jetons d'identité OIDC émis pour des audiences externes ne sont pas liés au certificat d'exécution.

L'exemple suivant utilise la bibliothèque google-auth pour demander un jeton d'ID OIDC et l'associer en tant que jeton Bearer dans une requête sortante :

Python

from google.auth.transport.requests import AuthorizedSession
from google.oauth2 import id_token

# 1. Specify the audience expected by the external receiver
# (for example, AWS Bedrock AgentCore or your external service URL).
target_audience = "https://EXTERNAL_SERVICE_AUDIENCE"

# 2. Create ID token credentials and an AuthorizedSession, which handles
# local token caching, automatic renewal before expiry, and the Bearer header.
credentials = id_token.fetch_id_token_credentials(audience=target_audience)
authed_session = AuthorizedSession(credentials)

# 3. Send the authenticated request to the external service.
response = authed_session.post(
    "https://EXTERNAL_SERVICE_ENDPOINT",
    json={"prompt": "Hello from Agent"},
)

Remplacez les éléments suivants :

  • EXTERNAL_SERVICE_AUDIENCE : URI d'audience attendu par votre service de réception (par exemple, bedrock.us-east-1.amazonaws.com ou api.example.com).
  • EXTERNAL_SERVICE_ENDPOINT : URL du point de terminaison de l'API externe ou du backend que votre agent appelle.

Pour obtenir des instructions et des exemples de bibliothèques clientes dans d'autres langages de programmation (y compris Go, Node.js et Java), consultez Obtenir un jeton d'identité. Les versions actuelles des bibliothèques clientes pour ces langages sont compatibles avec --identity-type=agent-identity, mais n'utilisent pas de jetons liés par défaut.

Valider les jetons d'identité de l'agent

Lorsqu'un service externe reçoit un jeton d'identification OIDC de votre agent, validez le jeton en utilisant l'une des approches suivantes en fonction du service cible :

Utiliser la fédération d'identité de charge de travail intégrée

Si votre service de réception s'exécute sur une plate-forme cloud compatible avec l'authentification IAM intégrée ou la fédération d'identité de charge de travail OIDC, vous n'avez pas besoin d'écrire de code de validation de jeton personnalisé :

  • Cloud Run : si votre service de réception s'exécute sur Cloud Run avec une entrée authentifiée (--no-allow-unauthenticated), Cloud Run valide les jetons d'identité de l'agent entrants au niveau de l'entrée. Accordez à l'agent appelant le rôle Demandeur Cloud Run (roles/run.invoker) sur le service de réception. Pour en savoir plus, consultez S'authentifier auprès des serveurs MCP sur Cloud Run.

    Si votre service autorise l'entrée non authentifiée et vérifie les jetons dans le code de l'application, consultez Vérifier les jetons de manière programmatique.

  • Amazon Bedrock : configurez l'authentification JWT entrante en spécifiant l'URL de découverte du service de jeton de sécuritéGoogle Cloud ou l'URL de l'émetteur, ainsi que votre audience attendue. Pour obtenir des instructions, consultez Configurer un autorisateur JWT entrant dans la documentation AWS.

  • Microsoft Entra ID : configurez un identifiant d'identité fédérée avec le scénario Autre émetteur. Spécifiez l'URL de l'émetteur du service Google Cloud Security Token Service, l'audience attendue et l'identifiant du sujet (revendication sub). Pour obtenir des instructions, consultez Créer une relation de confiance entre une application et un fournisseur d'identité externe dans la documentation Microsoft Learn.

Valider les jetons de manière programmatique

Si votre agent envoie des requêtes à une API personnalisée, à un microservice, à une passerelle API ou à une charge de travail sur site, votre service de réception doit valider le jeton d'identité OIDC entrant avant d'accorder l'accès. Votre agent transmet généralement ce jeton dans l'en-tête HTTP Authorization: Bearer TOKEN.

Pour valider les jetons d'identité entrants de manière programmatique, procédez comme suit :

  1. Extraire et valider l'URL de l'émetteur du jeton
  2. Découvrir et mettre en cache les clés de signature publiques
  3. Vérifier la signature et les revendications du jeton
  4. Autoriser l'identité SPIFFE de l'agent

Extraire et valider l'URL de l'émetteur du jeton

Lorsqu'une requête entrante arrive, lisez la charge utile JWT non validée pour extraire la revendication iss (émetteur). Cette revendication contient l'URL du pool d'identités de charge de travail pour le domaine de confiance de l'agent. Cette URL sert d'URL de base pour le document de découverte et les clés de signature publiques.

Avant d'effectuer des requêtes réseau sortantes, vérifiez que la revendication iss correspond à l'URL du pool d'identités de charge de travail du service de jetons de sécurité Google Cloud attendue pour votre organisation ou votre projet :

  • Domaines de confiance au niveau de l'organisation :

    https://sts.googleapis.com/v1/organizations/ORGANIZATION_ID/locations/global/workloadIdentityPools/TRUST_DOMAIN

    Par exemple, pour une organisation dont l'ID est 123456789012, TRUST_DOMAIN est agents.global.org-123456789012.system.id.goog.

  • Domaines de confiance au niveau du projet (pour les projets sans organisation) :

    https://sts.googleapis.com/v1/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/TRUST_DOMAIN

    Par exemple, pour un projet dont le numéro est 9876543210, TRUST_DOMAIN correspond à agents.global.proj-9876543210.system.id.goog.

Découvrir et mettre en cache les clés de signature publiques

Une fois l'URL de l'émetteur validée, récupérez et mettez en cache les clés de signature publiques à partir du service de jetons de sécurité Google Cloud  :

  1. Interrogez le point de terminaison OpenID Connect Discovery : ajoutez /.well-known/openid-configuration à l'URL de l'émetteur de base et envoyez une requête HTTP GET non authentifiée :

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

    • ORGANIZATION_ID : ID de votre organisation Google Cloud. Pour un projet sans organisation, remplacez organizations/ORGANIZATION_ID par projects/PROJECT_NUMBER.
    • TRUST_DOMAIN : ID du pool d'identités de charge de travail pour le domaine de confiance de votre agent (par exemple, agents.global.org-123456789012.system.id.goog).

    Méthode HTTP et URL :

    GET https://sts.googleapis.com/v1/organizations/ORGANIZATION_ID/locations/global/workloadIdentityPools/TRUST_DOMAIN/.well-known/openid-configuration

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

    Une requête réussie renvoie un état HTTP 200 OK et un objet JSON contenant les métadonnées du fournisseur OpenID, y compris le champ jwks_uri :

    {
      "issuer": "https://sts.googleapis.com/v1/organizations/123456789012/locations/global/workloadIdentityPools/agents.global.org-123456789012.system.id.goog",
      "jwks_uri": "https://sts.googleapis.com/v1/organizations/123456789012/locations/global/workloadIdentityPools/agents.global.org-123456789012.system.id.goog/openid/jwks",
      "authorization_endpoint": "https://sts.googleapis.com/v1/organizations/123456789012/locations/global/workloadIdentityPools/agents.global.org-123456789012.system.id.goog/authorize",
      "token_endpoint": "https://sts.googleapis.com/v1/organizations/123456789012/locations/global/workloadIdentityPools/agents.global.org-123456789012.system.id.goog/token",
      "response_types_supported": [
        "id_token"
      ],
      "subject_types_supported": [
        "public"
      ],
      "id_token_signing_alg_values_supported": [
        "RS256"
      ]
    }
    
  2. Interrogez le point de terminaison du jeu de clés Web JSON (JWKS) : envoyez une requête HTTP GET non authentifiée à l'URL jwks_uri renvoyée dans les métadonnées du fournisseur OpenID :

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

    • ORGANIZATION_ID : ID de votre organisation Google Cloud. Pour un projet sans organisation, remplacez organizations/ORGANIZATION_ID par projects/PROJECT_NUMBER.
    • TRUST_DOMAIN : ID du pool d'identités de charge de travail pour le domaine de confiance de votre agent (par exemple, agents.global.org-123456789012.system.id.goog).

    Méthode HTTP et URL :

    GET https://sts.googleapis.com/v1/organizations/ORGANIZATION_ID/locations/global/workloadIdentityPools/TRUST_DOMAIN/openid/jwks

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

    Une requête ayant abouti renvoie un état HTTP 200 OK et un objet JSON contenant un tableau de clés publiques mises en forme conformément à la RFC 7517 :

    {
      "keys": [
        {
          "kty": "RSA",
          "use": "sig",
          "alg": "RS256",
          "kid": "4d1933f8e6c4e0b512c140989f6655c68997...",
          "n": "uQn4zN_1mQ0VpGv82-Wp3w...",
          "e": "AQAB"
        }
      ]
    }
    
  3. Mettre en cache le document de découverte et les clés : les réponses du point de terminaison OpenID Connect Discovery et du point de terminaison JWKS incluent l'en-tête de cache HTTP suivant :

    Cache-Control: public, max-age=86400, must-revalidate
    

    Mettez en cache le document de découverte et le JWKS pendant 24 heures maximum (86400 secondes) pour améliorer les performances de validation et éviter la limitation du débit.

    Google Cloud alterne régulièrement les clés de signature privées et publiques pour les pools d'identités de charge de travail. Si votre vérificateur reçoit un jeton entrant avec un kid (ID de clé) qui ne figure pas dans son cache de clés local, récupérez un nouveau JWKS à partir du point de terminaison /openid/jwks avant de refuser le jeton.

    Si vous rencontrez des erreurs HTTP lorsque vous interrogez les points de terminaison de découverte ou JWKS, consultez Résoudre les problèmes d'authentification de l'Agent Identity.

Vérifier la signature et les revendications du jeton

Pour valider de manière cryptographique la signature du jeton et les revendications JWT, utilisez une bibliothèque de validation OIDC ou JWT standard (telle que Google Tink) et procédez comme suit :

  1. Signature : recherchez la clé publique dans le JWKS mis en cache qui correspond à kid (ID de clé) dans l'en-tête JWT. Validez la signature à l'aide de l'algorithme spécifié dans le champ alg (RS256). Pour assurer la compatibilité ascendante, inspectez les champs alg et kty dans le JWKS de manière dynamique plutôt que de coder en dur les types d'algorithmes.
  2. Émetteur (iss) : vérifiez que la revendication iss correspond à l'URL d'émetteur du pool d'identités de charge de travailGoogle Cloud approuvée pour votre domaine approuvé.
  3. Audience (aud) : vérifiez que la revendication aud correspond à l'identifiant d'audience configuré pour votre service.
  4. Heure d'émission (iat) et heure d'expiration (exp) : vérifiez que la revendication iat est dans le passé et que l'heure actuelle est antérieure à la revendication exp (en prévoyant une petite marge de tolérance pour le décalage horaire, par exemple une à deux minutes).

L'exemple suivant utilise Google Tink (tink.jwt) pour valider un jeton d'identité d'agent par rapport à une charge utile JSON JWKS :

Python

import tink
from tink import jwt

# Initialize Tink JWT signature primitives (call once at application startup).
jwt.register_jwt_signature()


def verify_agent_identity_token(
    token: str,
    jwks_json: str,
    expected_issuer: str,
    expected_audience: str,
) -> jwt.VerifiedJwt:
    """Verifies an Agent Identity JWT against a JWKS JSON string using Tink.

    Args:
        token: The compact serialized JWT string.
        jwks_json: The JWKS JSON string fetched from the STS pool endpoint.
        expected_issuer: The expected token issuer ('iss' claim).
        expected_audience: The expected token audience ('aud' claim).

    Returns:
        jwt.VerifiedJwt: The verified JWT claims object.

    Raises:
        tink.TinkError: If the JWKS cannot be parsed, the key is not found,
            or token validation (signature, issuer, audience, expiration) fails.
    """
    # 1. Convert the JWKS JSON into a Tink public KeysetHandle.
    keyset_handle = jwt.jwk_set_to_public_keyset_handle(jwks_json)

    # 2. Instantiate the Tink JwtPublicKeyVerify primitive.
    jwt_verifier = keyset_handle.primitive(jwt.JwtPublicKeyVerify)

    # 3. Configure expected validation rules (issuer, audience, expiration).
    # Google Cloud STS sets 'typ': 'JWT' in the header, so
    # expected_type_header="JWT" is required.
    validator = jwt.new_validator(
        expected_issuer=expected_issuer,
        expected_audience=expected_audience,
        expected_type_header="JWT",
        allow_missing_expiration=False,
    )

    # 4. Cryptographically verify the signature and standard OIDC claims.
    return jwt_verifier.verify_and_decode(token, validator)

Autoriser l'identité SPIFFE de l'agent

Après avoir vérifié la signature et les revendications standards du jeton, inspectez la revendication sub (sujet) validée pour autoriser la requête et enregistrer l'agent appelant dans vos journaux d'audit.

La revendication sub contient l'ID SPIFFE unique de l'agent, par exemple :

  spiffe://agents.global.org-123456789012.system.id.goog/resources/aiplatform/projects/9876543210/locations/us-central1/reasoningEngines/my-test-agent

Dans la logique d'autorisation de votre service, comparez la revendication sub validée à une liste d'autorisation des ID SPIFFE d'agent de confiance (ou des préfixes de domaine de confiance) avant d'accorder l'accès aux ressources protégées.

Étapes suivantes