Autenticación en servicios externos con la identidad propia de un agente

Los agentes alojados en Google Cloud pueden usar su propia identidad para autenticarse en herramientas y servicios alojados en los entornos de ejecución de Google Cloud , como Cloud Run o Google Kubernetes Engine (GKE), solicitando un token de ID de OpenID Connect (OIDC) a Agent Identity. Los agentes también pueden usar estos tokens de ID para autenticarse en plataformas de terceros en la nube (como Amazon Web Services [AWS] y Microsoft Azure), APIs personalizadas, puertas de enlace de API y backends locales.

Cuando un agente actúa por su propia autoridad para acceder a un servicio externo, Agent Identity emite un token de ID de OpenID Connect (OIDC). Este token web JSON (JWT) confirma la identidad SPIFFE del agente y está firmado por las claves de la entidad emisora para el dominio de confianza del agente (grupo de identidades para cargas de trabajo administradas). Los sistemas externos pueden verificar estos tokens sin Google Cloud credenciales ni SDKs a través de endpoints públicos alojados por el Google Cloud servicio de tokens de seguridad:

  • Un extremo de OpenID Connect Discovery 1.0 (/.well-known/openid-configuration) que publica los metadatos del proveedor de OpenID y el extremo de clave pública (jwks_uri).
  • Un extremo del conjunto de claves web JSON (JWKS) (/openid/jwks) que entrega las claves públicas activas que se usan para verificar las firmas en los tokens de ID del agente

Antes de comenzar

  1. Verifica que hayas elegido el método de autenticación correcto. Revisa cómo funcionan las identidades SPIFFE, los dominios de confianza y las credenciales de agentes en la descripción general de la identidad del agente.
  2. Crea e implementa un agente con la identidad del agente habilitada.
  3. Asegúrate de que tu servicio externo o proveedor de identidad cumpla con los siguientes requisitos:
  4. Identifica los siguientes valores de configuración para tu agente y el servicio externo de destino:
    • URL del emisor (reclamación iss): Es la URL del emisor del grupo de identidades para cargas de trabajo de tu organización (https://sts.googleapis.com/v1/organizations/ORGANIZATION_ID/locations/global/workloadIdentityPools/TRUST_DOMAIN) o proyecto (https://sts.googleapis.com/v1/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/TRUST_DOMAIN).
    • Público permitido (reclamación aud): Es el URI de público que espera el servicio externo o el proveedor de identidad cuando valida tokens de ID.
  5. Verifica que tengas los roles necesarios para completar esta tarea.

Roles obligatorios

Para obtener los permisos que necesitas para implementar un agente con Agent Identity, pídele a tu administrador que te otorgue los siguientes roles de IAM en tu proyecto:

Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.

Estos roles predefinidos contienen los permisos necesarios para implementar un agente con identidad del agente. Para ver los permisos exactos que son necesarios, expande la sección Permisos requeridos:

Permisos necesarios

Se requieren los siguientes permisos para implementar un agente con identidad del agente:

  • Implementa un agente en Agent Runtime en Gemini Enterprise Agent Platform:
    • aiplatform.reasoningEngines.create
    • aiplatform.reasoningEngines.update
  • Implementa un servicio de agente en Cloud Run:
    • run.services.create
    • run.services.update

También puedes obtener estos permisos con roles personalizados o con otros roles predefinidos.

Obtén un token de ID de OIDC para un agente

Para configurar tu agente de modo que obtenga y envíe un token de ID de OIDC a un servicio externo, completa las siguientes tareas:

  1. Configura tu agente con la identidad del agente
  2. Solicita un token de ID de OIDC en el código de la aplicación

Configura tu agente con Agent Identity

Habilita la identidad del agente cuando implementes tu agente:

  • Si implementas tu agente en Agent Runtime en Gemini Enterprise Agent Platform, configura identity_type como 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 implementas un servicio de agente alojado en contenedores en Cloud Run, pasa la marca --identity-type=agent-identity:

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

    Reemplaza lo siguiente:

    • SERVICE_NAME: Es el nombre de tu servicio de Cloud Run.
    • IMAGE_URL: Es la URL de la imagen del contenedor de tu agente.

Solicita un token de ID de OIDC en el código de la aplicación

En el código de la aplicación de tu agente, usa la biblioteca cliente de Google Auth para solicitar un token de ID de OIDC para tu público externo objetivo. La biblioteca cliente controla la generación de tokens, el almacenamiento en caché local y la renovación automática desde el servidor de metadatos.

De forma predeterminada, los tokens de ID de OIDC emitidos para públicos externos no están vinculados al certificado de tiempo de ejecución.

En el siguiente ejemplo, se usa la biblioteca google-auth para solicitar un token de ID de OIDC y adjuntarlo como un token Bearer en una solicitud saliente:

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"},
)

Reemplaza lo siguiente:

  • EXTERNAL_SERVICE_AUDIENCE: Es el URI del público esperado por tu servicio receptor (por ejemplo, bedrock.us-east-1.amazonaws.com o api.example.com).
  • EXTERNAL_SERVICE_ENDPOINT: Es la URL del extremo de la API externa o del backend al que llama tu agente.

Si deseas obtener instrucciones y ejemplos de la biblioteca cliente en otros lenguajes de programación (incluidos Go, Node.js y Java), consulta Cómo obtener un token de ID. Las versiones actuales de biblioteca cliente para estos lenguajes admiten --identity-type=agent-identity, pero no usan tokens vinculados de forma predeterminada.

Verifica los tokens de ID de identidad del agente

Cuando un servicio externo recibe un token de ID de OIDC de tu agente, verifica el token con uno de los siguientes enfoques según el servicio de destino:

Usa la federación de identidades para cargas de trabajo integrada

Si tu servicio receptor se ejecuta en una plataforma de nube que admite la autenticación integrada de IAM o la federación de identidades para cargas de trabajo de OIDC, no necesitas escribir código de verificación de tokens personalizado:

  • Cloud Run: Si tu servicio receptor se ejecuta en Cloud Run con entrada autenticada (--no-allow-unauthenticated), Cloud Run valida los tokens de Agent Identity entrantes en la capa de entrada. Otorga al agente de llamada el rol de Cloud Run Invoker (roles/run.invoker) en el servicio receptor. Para obtener más información, consulta Autentícate en servidores de MCP en Cloud Run.

    Si tu servicio permite la entrada sin autenticación y verifica los tokens en el código de la aplicación, consulta Cómo verificar tokens de forma programática.

  • Amazon Bedrock: Configura la autenticación de JWT entrante especificando la URL de detección delGoogle Cloud Servicio de token de seguridad o la URL del emisor, y tu público esperado. Para obtener instrucciones, consulta Configura un autorizador de JWT entrante en la documentación de AWS.

  • Microsoft Entra ID: Configura una credencial de identidad federada con la situación de Otro emisor. Especifica la URL del emisor del servicio de tokens de seguridad Google Cloud , el público esperado y el identificador del sujeto (reclamación sub). Para obtener instrucciones, consulta Crea una relación de confianza entre una app y un proveedor de identidad externo en la documentación de Microsoft Learn.

Verifica tokens de forma programática

Si tu agente envía solicitudes a una API personalizada, un microservicio, una puerta de enlace de API o una carga de trabajo local, tu servicio receptor debe verificar el token de ID de OIDC entrante antes de otorgar acceso. Por lo general, tu agente pasa este token en el encabezado HTTP Authorization: Bearer TOKEN.

Para verificar los tokens de ID entrantes de forma programática, completa las siguientes tareas:

  1. Extrae y valida la URL de la entidad emisora del token
  2. Descubre y almacena en caché las claves de firma públicas
  3. Verifica la firma y las declaraciones del token
  4. Autoriza la identidad de SPIFFE del agente

Extrae y valida la URL del emisor del token

Cuando llega una solicitud entrante, lee la carga útil del JWT no verificado para extraer el reclamo iss (emisor). Este reclamo contiene la URL del grupo de identidades para cargas de trabajo del dominio de confianza del agente. Esta URL sirve como URL base para el documento de descubrimiento y las claves de firma públicas.

Antes de realizar cualquier solicitud de red saliente, verifica que el reclamo iss coincida con la URL esperada del grupo de identidades para cargas de trabajo del Servicio de token de seguridad Google Cloud para tu organización o proyecto:

  • Dominios de confianza a nivel de la organización:

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

    Por ejemplo, para una organización con el ID 123456789012, TRUST_DOMAIN es agents.global.org-123456789012.system.id.goog.

  • Dominios de confianza a nivel del proyecto (para proyectos sin una organización):

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

    Por ejemplo, para un proyecto con el número 9876543210, TRUST_DOMAIN es agents.global.proj-9876543210.system.id.goog.

Descubre y almacena en caché las claves de firma públicas

Después de validar la URL del emisor, recupera y almacena en caché las claves de firma públicas del Servicio de tokens de seguridad de Google Cloud :

  1. Consulta el extremo de OpenID Connect Discovery: Agrega /.well-known/openid-configuration a la URL base de la entidad emisora y envía una solicitud GET HTTP sin autenticar:

    Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

    • ORGANIZATION_ID: Es el ID de tu organización Google Cloud. Para un proyecto sin una organización, reemplaza organizations/ORGANIZATION_ID por projects/PROJECT_NUMBER.
    • TRUST_DOMAIN: Es el ID del grupo de identidades para cargas de trabajo del dominio de confianza de tu agente (por ejemplo, agents.global.org-123456789012.system.id.goog).

    Método HTTP y URL:

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

    Para enviar tu solicitud, expande una de estas opciones:

    Si la solicitud se realiza correctamente, se devuelve un estado HTTP 200 OK y un objeto JSON que contiene los metadatos del proveedor de OpenID, incluido el campo 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. Consulta el extremo del conjunto de claves web JSON (JWKS): Envía una solicitud GET HTTP no autenticada a la URL jwks_uri que se devolvió en los metadatos del proveedor de OpenID:

    Antes de usar cualquiera de los datos de solicitud a continuación, realiza los siguientes reemplazos:

    • ORGANIZATION_ID: Es el ID de tu organización Google Cloud. Para un proyecto sin una organización, reemplaza organizations/ORGANIZATION_ID por projects/PROJECT_NUMBER.
    • TRUST_DOMAIN: Es el ID del grupo de identidades para cargas de trabajo del dominio de confianza de tu agente (por ejemplo, agents.global.org-123456789012.system.id.goog).

    Método HTTP y URL:

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

    Para enviar tu solicitud, expande una de estas opciones:

    Una solicitud exitosa devuelve un estado HTTP 200 OK y un objeto JSON que contiene un array de claves públicas con el formato de RFC 7517:

    {
      "keys": [
        {
          "kty": "RSA",
          "use": "sig",
          "alg": "RS256",
          "kid": "4d1933f8e6c4e0b512c140989f6655c68997...",
          "n": "uQn4zN_1mQ0VpGv82-Wp3w...",
          "e": "AQAB"
        }
      ]
    }
    
  3. Almacena en caché el documento de descubrimiento y las claves: Las respuestas del endpoint de descubrimiento de OpenID Connect y del endpoint de JWKS incluyen el siguiente encabezado de caché HTTP:

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

    Almacena en caché el documento de descubrimiento y el JWKS por hasta 24 horas (86400 segundos) para mejorar el rendimiento de la verificación y evitar la límite de frecuencia.

    Google Cloud rota periódicamente las claves de firma privadas y públicas para los grupos de identidades para cargas de trabajo. Si tu verificador recibe un token entrante con un kid (ID de clave) que no está en su caché de claves local, recupera un JWKS nuevo del extremo /openid/jwks antes de rechazar el token.

    Si encuentras errores HTTP cuando consultas los extremos de descubrimiento o JWKS, consulta Soluciona problemas de autenticación de Agent Identity.

Verifica la firma y las declaraciones del token

Para verificar de forma criptográfica la firma del token y validar las reclamaciones del JWT, usa una biblioteca de verificación de OIDC o JWT estándar (como Google Tink) y haz lo siguiente:

  1. Firma: Busca la clave pública en el JWKS almacenado en caché que coincida con el kid (ID de clave) en el encabezado del JWT. Valida la firma con el algoritmo especificado en el campo alg (RS256). Para garantizar la compatibilidad con versiones futuras, inspecciona los campos alg y kty en el JWKS de forma dinámica en lugar de codificar de forma rígida los tipos de algoritmos.
  2. Emisor (iss): Confirma que el reclamo iss coincida con la URL del emisor del grupo de identidades para cargas de trabajoGoogle Cloud de confianza para tu dominio de confianza.
  3. Público (aud): Confirma que el reclamo aud coincida con el identificador de público configurado de tu servicio.
  4. Hora de emisión (iat) y hora de vencimiento (exp): Verifica que el reclamo iat sea anterior y que la hora actual sea anterior al reclamo exp (lo que permite una pequeña tolerancia de desviación del reloj, como de 1 a 2 minutos).

En el siguiente ejemplo, se usa Google Tink (tink.jwt) para verificar un token de ID de Agent Identity en una carga útil de JWKS JSON:

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)

Autoriza la identidad SPIFFE del agente

Después de verificar la firma y los reclamos estándar del token, inspecciona el reclamo sub (sujeto) verificado para autorizar la solicitud y registrar el agente de llamada en tus registros de auditoría.

El reclamo sub contiene el ID de SPIFFE único del agente, por ejemplo:

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

En la lógica de autorización de tu servicio, compara el reclamo sub verificado con una lista de entidades permitidas de IDs de SPIFFE de agentes de confianza (o prefijos de dominios de confianza) antes de otorgar acceso a los recursos protegidos.

¿Qué sigue?