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

La identidad del agente permite que tus agentes Google Cloud usen su propia identidad para autenticarse en servicios externos y en cargas de trabajo alojadas en Cloud Run o Google Kubernetes Engine (GKE). Si usas tokens de ID de OpenID Connect (OIDC), puedes conectar agentes a plataformas de nube de terceros, como Amazon Web Services (AWS) y Microsoft Azure, APIs personalizadas, API Gateways y backends locales.

Cuando un agente actúa por su propia autoridad, la identidad del agente emite un token de ID de OIDC, que es un token web JSON (JWT) que declara 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 administrado). Los sistemas externos pueden verificar estos tokens de ID sin Google Cloud credenciales ni SDKs a través de extremos 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 de 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.

Para autenticar tu agente en las Google Cloud APIs y los recursos con su propia identidad, consulta Autentícate en Google Cloud con la propia identidad de un agente. Para acceder a los servicios en nombre de un usuario final, consulta Autentícate con OAuth de 3 segmentos con el administrador de autenticación.

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 del agente 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 de la entidad emisora (iss claim): La URL de la entidad emisora 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 (aud claim): El URI de público que espera el servicio externo o el proveedor de identidad cuando valida los 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 la identidad del agente, 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 la 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 la 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 otros roles predefinidos.

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

Para configurar tu agente para obtener y enviar 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 la identidad del agente

Habilita la identidad del agente cuando implementes tu agente:

  • Si implementas tu agente en Agent Runtime en Gemini Enterprise Agent Platform , establece identity_type en 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 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: El nombre de tu servicio de Cloud Run.
    • IMAGE_URL: La URL de la imagen de 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 de destino. 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, las bibliotecas cliente de Google Auth compatibles vinculan criptográficamente los tokens de ID de OIDC al certificado X.509 único del agente mediante la inclusión de la huella digital del certificado en la reclamación cnf (x5t#S256) del token. Los servicios de recepción pueden validar de forma opcional esta reclamación con el certificado de cliente presentado durante un protocolo de enlace de TLS mutua (mTLS) o ignorar la reclamación si no aplican la vinculación de certificados.

Cloud Run aplica automáticamente la vinculación de certificados cuando la reclamación cnf está presente en un token de ID. Si tu agente llama a un servicio de Cloud Run con un token de ID vinculado, debes llamar a su extremo de mTLS (*.mtls.run.app) a través de una conexión mTLS. Para seguir llamando a una URL *.run.app estándar, inhabilita la vinculación de certificados por solicitud (por ejemplo, configurando bind_id_token=False en Python) o en todo el entorno de ejecución con GOOGLE_API_ENABLE_RUNTIME_BOUND_TOKEN=false. Para obtener ejemplos y versiones de bibliotecas compatibles, consulta Inhabilitar tokens vinculados a certificados.

Cuando llames a un extremo que aplique la vinculación de certificados a través de mTLS, configura la sesión del cliente para que presente el certificado X.509 del agente durante el protocolo de enlace de mTLS (por ejemplo, llamando a authed_session.configure_mtls_channel() en Python).

En los siguientes ejemplos, se usa la biblioteca google-auth para solicitar un token de ID de OIDC vinculado a un certificado, configurar de forma opcional el canal de mTLS y adjuntar el token 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: El URI de público que espera tu servicio de recepción (por ejemplo, bedrock.us-east-1.amazonaws.com o api.example.com).
  • EXTERNAL_SERVICE_ENDPOINT: La URL de la API externa o el extremo de backend al que llama tu agente.

Python (mTLS)

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

# 1. Specify the audience expected by the receiving service
# (for example, a regional Cloud Run mTLS URL or an on-premises mTLS endpoint).
target_audience = "https://EXTERNAL_SERVICE_AUDIENCE"

# 2. Create certificate-bound ID token credentials and configure the mTLS
# channel to present the agent's X.509 certificate.
credentials = id_token.fetch_id_token_credentials(audience=target_audience)
authed_session = AuthorizedSession(credentials)
authed_session.configure_mtls_channel()

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

Reemplaza lo siguiente:

  • EXTERNAL_SERVICE_AUDIENCE: El URI de público que espera tu servicio de recepción (por ejemplo, una URL de mTLS regional de Cloud Run o api.example.com).
  • EXTERNAL_SERVICE_ENDPOINT: La URL de la API de mTLS o el extremo de backend al que llama tu agente.

Para obtener instrucciones y ejemplos de biblioteca cliente en otros lenguajes, como Go, Node.js y Java, consulta Obtén un token de ID. Las bibliotecas cliente para estos lenguajes admiten --identity-type=agent-identity. Las bibliotecas que admiten tokens de ID vinculados a certificados vinculan tokens de forma predeterminada y te permiten inhabilitarlos para solicitudes individuales.

Verifica los tokens de ID de la identidad del agente

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

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

Si tu servicio de recepción se ejecuta en una plataforma de nube que admite la autenticación de IAM integrada 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 de recepción se ejecuta en Cloud Run con entrada autenticada (--no-allow-unauthenticated), Cloud Run valida los tokens de identidad del agente entrantes en la capa de entrada. Cuando el token incluye la reclamación cnf, configura el agente que llama para que se oriente a la URL de mTLS regional del servicio de recepción (https://SERVICE_NAME-PROJECT_NUMBER.REGION.mtls.run.app) para que Cloud Run pueda validar el certificado de cliente durante el protocolo de enlace de mTLS. Otorga al agente que llama el rol de invocador de Cloud Run (roles/run.invoker) en el servicio de recepción. Para obtener más información, consulta Autentícate en servidores de MCP en Cloud Run.

    Si tu servicio permite la entrada no autenticada y verifica los tokens en el código de la aplicación, consulta Verifica los tokens de manera programática.

  • Amazon Bedrock: Configura la autenticación de JWT entrante especificando la Google Cloud URL de descubrimiento o la URL de la entidad emisora del servicio de tokens de seguridad y tu público esperado. Para obtener instrucciones, consulta Configura el autorizador de JWT entrante en la documentación de AWS.

  • Microsoft Entra ID: Configura una credencial de identidad federada con la situación Otra entidad emisora. Especifica la URL de la entidad emisora del Google Cloud servicio de tokens de seguridad, el público esperado y el identificador de asunto (sub reclamación). 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 los tokens de manera 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 de recepción debe verificar el token de ID de OIDC entrante antes de otorgar acceso. Por lo general, tu agente pasa este token en el Authorization: Bearer TOKEN encabezado HTTP.

Para verificar los tokens de ID entrantes de manera 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 reclamaciones del token
  4. Opcional: Valida la vinculación de certificados (reclamación cnf)
  5. Autoriza la identidad SPIFFE del agente

Extrae y valida la URL de la entidad emisora del token

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

Antes de realizar cualquier solicitud de red saliente, verifica que la reclamación iss coincida con la URL del grupo de identidades para cargas de trabajo del servicio de tokens de seguridad Google Cloud esperada 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 de la entidad emisora, recupera y almacena en caché las claves de firma públicas del Google Cloud servicio de tokens de seguridad:

  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 HTTP GET no autenticada:

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

    • ORGANIZATION_ID: Es el ID de tu Google Cloud organización. Para un proyecto sin una organización, reemplaza organizations/ORGANIZATION_ID con projects/PROJECT_NUMBER.
    • TRUST_DOMAIN: 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 muestra 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 HTTP GET no autenticada a la jwks_uri URL que se muestra 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 Google Cloud organización. Para un proyecto sin una organización, reemplaza organizations/ORGANIZATION_ID con projects/PROJECT_NUMBER.
    • TRUST_DOMAIN: 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:

    Si la solicitud se realiza correctamente, se muestra un estado HTTP 200 OK y un objeto JSON que contiene un array de claves públicas con el formato según 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 de ambos extremos, el de OpenID Connect Discovery y el 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 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 de HTTP cuando consultas los extremos de descubrimiento o JWKS, consulta Soluciona problemas de autenticación de la identidad del agente.

Verifica la firma y las reclamaciones del token

Para verificar criptográficamente la firma del token y validar las reclamaciones de 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 JWT. Valida la firma con el algoritmo especificado en el campo alg (RS256). Para la compatibilidad con versiones anteriores, inspecciona los campos alg y kty en el JWKS de forma dinámica en lugar de codificar de forma rígida los tipos de algoritmo.
  2. Entidad emisora (iss): Confirma que la reclamación iss coincida con la URL de la entidad emisora del grupo de identidades para cargas de trabajo de confianza Google Cloud para tu dominio de confianza.
  3. Público (aud): Confirma que la reclamación 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 la reclamación iat esté en el pasado y que la hora actual sea anterior a la reclamación 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 la identidad del agente con una carga útil de JSON de 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)

Opcional: Valida la vinculación de certificados (reclamación cnf)

Si tu servicio de recepción aplica la vinculación de certificados a través de mTLS, valida la reclamación cnf (x5t#S256) con el certificado de cliente presentado durante el protocolo de enlace de mTLS:

  1. Finaliza la TLS mutua (mTLS): Configura tu servidor o proxy de entrada para solicitar y validar el certificado X.509 del agente durante el protocolo de enlace TLS según TLS 1.3 (RFC 9846).
  2. Calcula la huella digital del certificado (x5t#S256): Extrae el certificado de cliente X.509 de hoja de la conexión mTLS. Calcula el hash SHA-256 sobre sus bytes codificados en DER y codifica el resumen en base64url sin relleno =.
  3. Valida la reclamación cnf (x5t#S256): Inspecciona la carga útil de JWT verificada para el objeto cnf ({"cnf": {"x5t#S256": "FINGERPRINT"}}) y verifica que el valor x5t#S256 coincida con la huella digital del certificado de cliente según la sección 6.1 de RFC 8705. Si la persona que llama no presentó un certificado de cliente a través de mTLS o si las huellas digitales no coinciden, rechaza la solicitud con una respuesta HTTP 401 Unauthorized.

Autoriza la identidad SPIFFE del agente

Después de verificar la firma del token y las reclamaciones estándar, inspecciona la reclamación sub (asunto) verificada para autorizar la solicitud y registrar el agente que llama en tus registros de auditoría.

La reclamación sub contiene el ID 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 la reclamación sub verificada con una lista de entidades permitidas de IDs SPIFFE de agentes de confianza (o prefijos de dominio de confianza) antes de otorgar acceso a los recursos protegidos.

¿Qué sigue?