Authentifizierung mit einer KI-Agentenidentität in GKE

GKE-Agents (Google Kubernetes Engine) mit einer Agentenidentität können diese Identität verwenden, um sich bei Google Cloud APIs und bei externen Tools und Diensten zu authentifizieren. Die Agenten können ihre eigene Identität verwenden oder im Namen von Endnutzern handeln. In diesem Dokument wird beschrieben, wie Entwickler von Agent-Anwendungen ihre Anwendungen für die Authentifizierung bei verschiedenen Ressourcen konfigurieren können. Sie sollten bereits wissen, wie Sie eine Agent-Identität für einen GKE-Agenten anfordern.

Je nachdem, auf welche Ressource der Agent zugreifen muss, muss Ihr Plattformadministrator möglicherweise den Auth Manager-Anmeldedatenspeicher konfigurieren, um zusätzliche Workflows auszuführen. Damit sich ein Agent beispielsweise im Namen eines Endnutzers bei GitHub authentifizieren kann, muss ein 3-legged-OAuth-Authentifizierungsanbieter im Authentifizierungsmanager die Nutzeranmeldung, Autorisierung und Weiterleitung verarbeiten. Als Entwickler müssen Sie Ihren Agent so anpassen, dass er den richtigen Authentifizierungsanbieter aufruft und die Unterhaltung für den Endnutzer fortsetzt.

Beschränkungen

  • Einschränkungen für die Identität von Kundenservicemitarbeitern
  • Sie können die Google-Authentifizierungsbibliothek verwenden, um gebundene Zugriffs- und ID-Tokens nur für Python abzurufen. Die Authentifizierungsbibliothek ruft möglicherweise keine gebundenen Tokens für andere Sprachen ab. Wenn Sie eine andere Sprache verwenden, wechseln Sie zu nicht gebundenen Tokens, indem Sie die Umgebungsvariable GOOGLE_API_ENABLE_RUNTIME_BOUND_TOKEN auf false festlegen.

Hinweis

Führen Sie die folgenden Aufgaben aus, bevor Sie beginnen:

  • Aktivieren Sie die Google Kubernetes Engine API.
  • Google Kubernetes Engine API aktivieren
  • Wenn Sie die Google Cloud CLI für diese Aufgabe verwenden möchten, müssen Sie die gcloud CLI installieren und dann initialisieren. Wenn Sie die gcloud CLI bereits installiert haben, rufen Sie die neueste Version mit dem Befehl gcloud components update ab. In früheren gcloud CLI-Versionen werden die Befehle in diesem Dokument möglicherweise nicht unterstützt.

Erforderliche Rollen

Bitten Sie Ihren Administrator, Ihnen die IAM-Rolle Kubernetes Engine Developer (roles/container.developer) für Ihr Projekt zuzuweisen, um die Berechtigungen zu erhalten, die Sie zum Konfigurieren bereitgestellter Agents in GKE-Clustern benötigen. Weitere Informationen zum Zuweisen von Rollen finden Sie unter Zugriff auf Projekte, Ordner und Organisationen verwalten.

Sie können die erforderlichen Berechtigungen auch über benutzerdefinierte Rollen oder andere vordefinierte Rollen erhalten.

Bei Google Cloud APIs authentifizieren

Um sich bei Google Cloud APIs als eigene Identität des Agenten zu authentifizieren, kann der Agent ein Zugriffstoken für die Agentenidentität vom Metadatenserver auf Ihren Knoten verwenden. Die Änderungen, die Sie an Ihrem Code vornehmen müssen, hängen davon ab, wie Sie Google Cloud APIs aufrufen.

Cloud-Clientbibliotheken verwenden

Wenn Sie eine Version der Cloud-Clientbibliotheken verwenden, die Version 2.61.0 oder höher der google-auth-Bibliothek enthält, wird automatisch ein Zugriffstoken für die Agentenidentität über die Standardanmeldedaten für Anwendungen (Application Default Credentials, ADC) abgerufen. Sie müssen keine zusätzlichen Änderungen an Ihrem Code vornehmen. Wenn Sie die Zertifikateinfügung für die Pods aktivieren, indem Sie die Annotation iam.gke.io/inject-podcertificates: "true" festlegen, wird das Zugriffstoken standardmäßig an das X.509-Zertifikat gebunden, sofern Sie gebundene Tokens nicht deaktivieren.

Wenn Sie die Cloud-Clientbibliotheken verwenden, haben Sie folgende Möglichkeiten, um nicht gebundene Zugriffstokens zu erhalten:

  • Aktivieren Sie die Zertifikatsinjektion in Ihrem Pod und legen Sie die Umgebungsvariable GOOGLE_API_ENABLE_RUNTIME_BOUND_TOKEN auf false fest.
  • Aktivieren Sie die Zertifikatsinjektion nicht in Ihrem Pod.

Direkte Aufrufe von Google Cloud API-Endpunkten verwenden

Wenn Sie die Cloud-Clientbibliotheken nicht für die Interaktion mit einem Dienst verwenden, können Sie die Identität des Agents zur Authentifizierung bei einer Google Cloud API verwenden. Gehen Sie dazu so vor:

  1. Rufen Sie ein Zugriffstoken vom Metadatenserver auf dem Knoten ab. Sie können ein Token mit einer der folgenden Methoden abrufen:

    • Gebundene Zugriffstokens: Verwenden Sie die Python-Bibliothek google-auth, die das X.509-Zertifikat des Pods erkennt und standardmäßig automatisch gebundene Zugriffstokens abruft. Verwenden Sie für andere Programmiersprachen ungebundene Tokens.

    • Ungebundene Zugriffstokens: Wenn der Pod nicht das Anmeldedatenpaket für die Agentenidentität hat, verwenden Sie die Google-Authentifizierungsbibliothek für Ihre Programmiersprache. Die Authentifizierungsbibliothek ruft automatisch nicht gebundene Zugriffstokens ab und aktualisiert ablaufende Tokens für Sie. Für Python-Anwendungen in Pods, die das Anmeldedaten-Bundle haben, legen Sie die Umgebungsvariable GOOGLE_API_ENABLE_RUNTIME_BOUND_TOKEN in der Pod-Spezifikation auf false fest, wie im folgenden Beispiel:

      # Multiple lines are omitted here.
      spec:
        containers:
        - name: example-agent
          image: example-image
          env:
          - name: GOOGLE_API_ENABLE_RUNTIME_BOUND_TOKEN
            value: "false"
      # Multiple lines are omitted here.
      

      Diese Umgebungsvariable verhindert, dass die Bibliothek gebundene Zugriffstokens und ID-Tokens abruft.

  2. Senden Sie die Anfrage für gebundene Zugriffstokens an den mTLS-Endpunkt der API und fügen Sie die X.509-Zertifikatkette der Agentenidentität in den HTTP-Transport ein. Wenn Sie die Google-Authentifizierungsbibliothek für Python verwenden, übernimmt die Bibliothek die HTTP-Transportkonfiguration für Sie.

Das folgende Beispiel zeigt, wie Sie mit der Google-Authentifizierungsbibliothek für Python ein gebundenes Zugriffstoken abrufen und eine Anfrage an den Cloud Storage-mTLS-Endpunkt senden:

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


def call_storage_api_mtls(bucket_name: str) -> None:
    # Discover the Pod's X.509 certificate chain by using the auth library
    credentials, project = google.auth.default(
        scopes=["https://www.googleapis.com/auth/cloud-platform"]
    )
    # Configure the mTLS session by using the Pod's certificate chain
    session = AuthorizedSession(credentials)
    session.configure_mtls_channel()
    # Call the Google Cloud mTLS endpoint
    mtls_url = f"https://storage.mtls.googleapis.com/storage/v1/b/{bucket_name}/o"
    response = session.get(mtls_url)
    response.raise_for_status()
    print(response.json())

Bei externen Tools und Diensten authentifizieren

Um sich bei externen Tools und Diensten zu authentifizieren, können Sie Ihren KI-Agenten so konfigurieren, dass er die erforderlichen Anmeldedaten vom Authentifizierungsmanager für die Identität von KI-Agenten abruft. Ein Plattformadministrator konfiguriert verschiedene Authentifizierungsanbieter im Authentifizierungsmanager, die jeweils bestimmte Authentifizierungs-Workflows und Anmeldedaten verwalten. Sie ändern Ihren Anwendungscode, um einen bestimmten Authentifizierungsanbieter aufzurufen und, je nach Authentifizierungsworkflow, die Nutzereinwilligung und die Wiederaufnahme von Unterhaltungen zu verarbeiten. Die spezifischen Änderungen, die Sie an Ihrem Agenten vornehmen, hängen davon ab, worauf Sie zugreifen müssen:

Der Authentifizierungsmanager verarbeitet die entsprechenden Authentifizierungs-Workflows und gewährt dem Agenten Zugriff auf die verschlüsselten Anmeldedaten, die dann in Anfragen an den externen Dienst aufgenommen werden können. Weitere Informationen dazu, was Ihr Plattformadministrator tun muss, um diese Authentifizierungsanbieter zu konfigurieren und Zugriff auf Ihre Agent-Identität zu gewähren, finden Sie unter Authentifizierungs-Workflows für Agents.

Bei anderen Agenten authentifizieren

In Multi-Agenten-Architekturen arbeiten Agents häufig zusammen, indem sie Peer-Agents oder Downstream-Dienste direkt aufrufen. Sie können die direkte Kommunikation zwischen Agent-Arbeitslasten mithilfe von Identitätstokens herstellen. Sie können ein gebundenes oder ein ungebundenes ID-Token vom GKE-Metadatenserver abrufen und dieses Token verwenden, um sich direkt bei anderen Agents zu authentifizieren.

Wenn Sie ein ID-Token abrufen und in einer HTTP-Anfrage verwenden möchten, verwenden Sie die Google-Authentifizierungsbibliothek für Python. Die Bibliothek übernimmt automatisch die Zertifikaterkennung und den Abruf von ID-Tokens. Wenn Sie eine andere Programmiersprache verwenden, werden möglicherweise keine gebundenen ID-Tokens von der Google-Authentifizierungsbibliothek abgerufen. Wechseln Sie stattdessen zu nicht gebundenen ID-Tokens.

ID-Token abrufen

Wenn Sie ein ID-Token in Ihrem Agent-Code anfordern möchten, verwenden Sie die Google-Authentifizierungsbibliothek für Ihre Programmiersprache. Sie können die Bibliothek verwenden, um gebundene oder ungebundene ID-Tokens anzufordern:

  • Gebundene ID-Tokens: Verwenden Sie die Annotation iam.gke.io/inject-podcertificates: "true", um die Zertifikatsinjektion für Ihren Pod zu aktivieren. Die Authentifizierungsbibliothek für Python fordert automatisch ein zertifikatgebundenes ID-Token vom GKE-Metadatenserver an. Verwenden Sie gebundene ID-Tokens, wenn Sie die Authentifizierung zwischen Agenten, die auf Google Cloud ausgeführt werden, mit mTLS durchführen.
  • Nicht gebundene ID-Tokens:

    • Aktivieren Sie die Zertifikatsinjektion für Ihren Pod und führen Sie einen der folgenden Schritte aus:
      • Legen Sie im Anwendungscode in der Funktion id_token.fetch_id_token das Argument bind_id_token auf den Wert False fest. Dieses Argument bewirkt, dass die Authentifizierungsbibliothek ungebundene ID-Tokens anfordert. Anfragen für Zugriffstokens sind davon nicht betroffen.
      • Legen Sie in der Pod-Spezifikation die Umgebungsvariable GOOGLE_API_ENABLE_RUNTIME_BOUND_TOKEN auf den Wert false fest. Diese Umgebungsvariable verhindert, dass die Bibliothek gebundene Zugriffstokens und ID-Tokens anfordert.
    • Aktivieren Sie die Zertifikatsinjektion nicht für Ihren Pod. Die Authentifizierungsbibliothek ruft ein ungebundenes ID-Token ab, da im Pod kein Anmeldedaten-Bundle vorhanden ist.

    Verwenden Sie nicht gebundene ID-Tokens, wenn Sie sich bei Google Cloud APIs, externen Diensten oder anderen Agents über eine Nicht-mTLS-Verbindung authentifizieren.

Die folgenden Beispiele zeigen, wie Sie ein gebundenes oder ungebundenes ID-Token für einen Agenten anfordern, für den die Anmeldedateninjektion aktiviert ist:

  • Gebundenes ID-Token anfordern:

    import google.auth.transport.requests
    from google.oauth2 import id_token
    
    # Application Default Credentials automatically requests a certificate-bound
    # ID token.
    def get_bound_id_token(target_audience: str) -> str:
        auth_req = google.auth.transport.requests.Request()
        return id_token.fetch_id_token(auth_req, audience=target_audience)
    

    Das gebundene Identitätstoken enthält den SHA-256-Zertifikat-Fingerabdruck der X.509-Zertifikatskette des Pods im Parameter cnf.x5t#S256.

  • Fordern Sie ein nicht gebundenes ID-Token an:

    import google.auth.transport.requests
    from google.oauth2 import id_token
    
    def get_unbound_id_token(target_audience: str) -> str:
        auth_req = google.auth.transport.requests.Request()
        return id_token.fetch_id_token(
            auth_req,
            audience=target_audience,
            # Always get an unbound ID token, even if the Pod has a credential
            # bundle.
            bind_id_token=False,
        )
    

ID-Token in einer Anfrage an einen anderen Agenten verwenden

Nachdem Sie ein ID-Token für Ihren Agent erhalten haben, können Sie das Token verwenden, um sich direkt bei einem anderen Agent zu authentifizieren. Wie Sie die Verbindung authentifizieren, hängt davon ab, ob Sie ein gebundenes ID-Token verwenden:

  • Stellen Sie für gebundene ID-Tokens eine mTLS-Verbindung mit dem empfangenden Agent her und authentifizieren Sie die Verbindung mit beiden der folgenden Anmeldedaten aus dem Verzeichnis /var/run/secrets/workload-spiffe-credentials/ im Pod:
    • Das Anmeldedatenpaket für die Agentenidentität in der Datei x509.credential-bundle.private-key.pem, das die Blattzertifikatskette für den Pod enthält.
    • Das Cluster-Trust-Bundle in der Datei TRUST_DOMAIN.spiffe-trust-bundle.pem. Diese Datei enthält das Stamm-CA-Zertifikat für den empfangenden Agent und wird verwendet, um die Zertifikatskette des empfangenden Agents während des mTLS-Handshakes zu validieren. Die anrufenden und empfangenden Agents müssen sich im selben Agent-Identitätspool befinden.
  • Stellen Sie für nicht gebundene ID-Tokens eine Nicht-mTLS-Verbindung mit dem empfangenden Agent her.

In den folgenden Beispielen wird gezeigt, wie Sie eine Anfrage an einen anderen Agenten senden, indem Sie ein gebundenes oder ungebundenes ID-Token verwenden:

  • Gebundenes ID-Token: Fügen Sie das gebundene Identitätstoken in den Authorization: Bearer-Header der Anfrage ein, die Sie an den mTLS-Endpunkt des empfangenden Agents senden. Authentifizieren Sie die TLS-Verbindung mit dem X.509-Zertifikat und dem privaten Schlüssel des Pods:

    import ssl
    import urllib3
    
    BUNDLE_PATH = "/var/run/secrets/workload-spiffe-credentials/x509.credential-bundle.private-key.pem"
    TRUST_BUNDLE_PATH = "/var/run/secrets/workload-spiffe-credentials/TRUST_DOMAIN.spiffe-trust-bundle.pem"
    
    def call_peer_agent_bound_mtls(target_mtls_url: str, target_audience: str) -> None:
    
        # Configure the mTLS context by using the certificate chain and trust
        # bundle from the Pod.
        ctx = ssl.create_default_context(cafile=TRUST_BUNDLE_PATH)
        ctx.load_cert_chain(BUNDLE_PATH)
        http = urllib3.PoolManager(ssl_context=ctx, assert_hostname=False)
    
        # Call a peer agent's mTLS endpoint by using the bound ID token and Pod
        # certificate chain.
        bound_id_token = get_bound_id_token(target_audience)
        response = http.request(
            "POST",
            target_mtls_url,
            headers={"Authorization": f"Bearer {bound_id_token}"},
            json={"task": "analyze_data"},
            timeout=10,
        )
        print(response.json())
    

    Ersetzen Sie TRUST_DOMAIN durch die Vertrauensdomain für Ihren Agent-Identitätspool.

  • Nicht gebundenes ID-Token: Fügen Sie das Token in den Authorization: Bearer-Header Ihrer Anfrage an den Peer-Agenten ein:

    import requests
    
    def call_peer_agent_unbound(target_url: str, target_audience: str) -> None:
        unbound_id_token = get_unbound_id_token(target_audience)
        # Send the request by using a standard TLS connection or plain HTTP.
        response = requests.post(
            target_url,
            headers={"Authorization": f"Bearer {unbound_id_token}"},
            json={"task": "analyze_data"},
            timeout=10,
        )
        response.raise_for_status()
        print(response.json())
    

Anfrage im empfangenden Agent validieren

Validieren Sie im empfangenden Agent das ID-Token in der eingehenden Anfrage, indem Sie Folgendes tun. Sie können kryptografische Bibliotheken wie Tink verwenden, um diese Überprüfungsschritte auszuführen, anstatt benutzerdefinierten Code zu schreiben.

  1. Extrahieren Sie das Identitätstoken aus dem Authorization: Bearer-Anfrageheader.
  2. Prüfen Sie, ob die Anforderung iss (Aussteller) im ID-Token der Agent Identity-Pool für den aufrufenden Agenten ist. Der Aussteller ist einer der folgenden, je nachdem, ob sich der aufrufende Agent in einem Projekt befindet, das zu einer Organisation gehört:
    • Projekt in einer Organisation: https://sts.googleapis.com/v1/organizations/ORGANIZATION_ID/locations/global/workloadIdentityPools/agents.global.org-ORGANIZATION_ID.system.id.goog, wobei ORGANIZATION_ID die Organisations-ID der Organisation ist, die das Projekt des aufrufenden Agents enthält.
    • Projekt, das nicht zu einer Organisation gehört: https://sts.googleapis.com/v1/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/agents.global.proj-PROJECT_NUMBER.system.id.goog, wobei PROJECT_NUMBER die Projektnummer des GKE-Cluster des aufrufenden Agents ist.
  3. Ermitteln Sie den URI des JSON Web Key Set (JWKS) für den Aussteller und speichern Sie die öffentlichen JSON Web Keys (JWKs) im Cache. Der Endpunkt für den JWKS hat das Format ISSUER_URL/openid/jwks, wobei ISSUER_URL die Aussteller-URL ist.
  4. Prüfen Sie die Tokensignatur anhand der folgenden Informationen aus dem JOSE-Header des ID-Tokens:
    • Der öffentliche JWK, der dem Header-Parameter kid entspricht.
    • Der kryptografische Algorithmus, der dem Header-Parameter alg entspricht, z. B. RS256.
  5. Prüfen Sie, ob der SHA-256-Zertifikat-Fingerabdruck im Parameter cnf.x5t#S256 mit dem Fingerabdruck des X.509-Zertifikats übereinstimmt, das der aufrufende Agent zur Authentifizierung der mTLS-Verbindung verwendet hat.
  6. Prüfen Sie die folgenden Ansprüche im ID-Token:
    • Die Ablaufzeit in der exp-Anforderung liegt in der Zukunft.
    • Die Zielgruppe im aud-Anspruch ist der empfangende Agent.
  7. Autorisieren Sie die Anfrage anhand der SPIFFE-ID, die in der sub-Anforderung (Betreff) des Tokens enthalten ist.

Nächste Schritte