---
title: WIF mit SPIFFE verwenden
url: https://platform.claude.com/docs/de/manage-claude/wif-providers/spiffe
description: Authentifiziere SPIFFE-Workloads gegenüber der Claude API mithilfe von JWT-SVIDs aus SPIRE oder einem beliebigen anderen SPIFFE-konformen Issuer.
---

[SPIFFE](https://spiffe.io/) ist der CNCF-Standard für die Ausstellung von Identitäten an Workloads. [SPIRE](https://spiffe.io/docs/latest/spire-about/) ist dessen Open-Source-Referenzimplementierung, und mehrere kommerzielle Produkte stellen ebenfalls SPIFFE-konforme Identitäten aus. Anthropic föderiert mit jeder SPIFFE-Implementierung, die OIDC-kompatible JWT-SVIDs ausgibt. Eine aktuelle Liste der Implementierungen findest du unter [Commercial software that implements SPIFFE](https://spiffe.io/docs/latest/spiffe-about/overview/#commercial-software-that-implements-spiffe) auf der Website des SPIFFE-Projekts.

Die Föderation funktioniert entweder über ein OIDC-Discovery-Dokument unter einer öffentlichen HTTPS-URL (`discovery`-Modus, unterliegt den [URL-Einschränkungen](https://platform.claude.com/docs/de/manage-claude/wif-reference#url-fields)) oder durch direkte Registrierung des JWKS (`inline`-Modus).

Die JWT-SVID-Spezifikation definiert `sub` als die SPIFFE-ID des Workloads, und die SPIFFE Workload API verlangt, dass der Aufrufer `aud` zum Abrufzeitpunkt angibt, sodass diese Claims über alle Implementierungen hinweg gleich sind. Anthropic verlangt zusätzlich `iss` und `iat`, die beide von der JWT-SVID-Spezifikation nicht vorgeschrieben werden. Konfiguriere deine Implementierung daher so, dass sie beide befüllt (in SPIRE ist `iss` die Server-Einstellung `jwt_issuer`, und `iat` wird automatisch gesetzt). Sobald diese vorhanden sind, gelten die Abschnitte [Anthropic konfigurieren](https://platform.claude.com/docs/de/manage-claude/wif-providers/spiffe#configure-anthropic), [Token abrufen und verwenden](https://platform.claude.com/docs/de/manage-claude/wif-providers/spiffe#acquire-and-use-the-token) und [Deine Regel eingrenzen](https://platform.claude.com/docs/de/manage-claude/wif-providers/spiffe#scope-your-rule) dieses Leitfadens für jede SPIFFE-Implementierung.

SPIFFE weist jedem Workload eine stabile Identitäts-URI der Form `spiffe://<trust-domain>/<path>` zu, und SPIRE stellt diese Identität bei Bedarf über die Workload API als JWT-SVID aus. Ein JWT-SVID ist ein gewöhnliches signiertes JWT, dessen `sub`-Claim die SPIFFE-ID des Workloads ist und dessen `aud`-Claim vom Workload zum Abrufzeitpunkt angegeben wird.

Die Brücke von einer SPIRE-Trust-Domain zu Standard-OIDC ist der [SPIRE OIDC Discovery Provider](https://github.com/spiffe/spire/blob/main/support/oidc-discovery-provider/README.md), ein eigenständiges Hilfsprogramm, das `/.well-known/openid-configuration` und einen JWKS-Endpunkt für die JWT-Signaturschlüssel der Trust-Domain veröffentlicht. Wenn der Discovery Provider läuft, wird ein JWT-SVID wie jedes andere OIDC-Token validiert: Registriere die Discovery-URL als Federation Issuer, schreibe eine Federation Rule, die auf die SPIFFE-ID des Workloads passt, und lass den Workload sein JWT-SVID am Token-Exchange-Endpunkt von Anthropic vorlegen.

Die Beispiele auf dieser Seite verwenden SPIRE und gelten überall, wo SPIRE Agent läuft: Kubernetes-Pods, virtuelle Maschinen und Bare-Metal-Hosts.

<Note>
  Wenn dein Kubernetes-Cluster kein SPIRE ausführt und du dich stattdessen mit den nativen projizierten Service-Account-Tokens des Clusters authentifizieren möchtest, siehe [WIF mit Kubernetes verwenden](https://platform.claude.com/docs/de/manage-claude/wif-providers/kubernetes).
</Note>

## Voraussetzungen

* Vertrautheit mit den [WIF-Konzepten](https://platform.claude.com/docs/de/manage-claude/workload-identity-federation#concepts): Service Accounts, Federation Issuers und Federation Rules.
* Ein SPIFFE-Deployment mit ausgestellten Workload-Identitäten (die Beispiele auf dieser Seite verwenden SPIRE Server und Agent) sowie Registrierungseinträge für die Workloads, die die Claude API aufrufen müssen.
* Ein OIDC-Discovery-Endpunkt für die Trust-Domain (in SPIRE der [OIDC Discovery Provider](https://github.com/spiffe/spire/blob/main/support/oidc-discovery-provider/README.md)), der mit einem öffentlich erreichbaren HTTPS-Endpunkt läuft, oder das für die `inline`-Registrierung exportierte JWKS.
* Dein SPIFFE-Issuer ist so konfiguriert, dass er den `iss`-Claim in JWT-SVIDs auf den Wert setzt, den du als `issuer_url` des Federation Issuers registrieren wirst. Im `discovery`-Modus ist dies die öffentliche URL des Discovery-Endpunkts (in SPIRE die Server-Einstellung `jwt_issuer`).
* JWT-SVIDs stehen deinen Workloads zur Verfügung. WIF akzeptiert nur JWT-SVIDs, keine X.509-SVIDs.
* Berechtigung zum Erstellen von Service Accounts, Federation Issuers und Federation Rules in der Claude Console für deine Anthropic-Organisation.

Der Audience-Wert, der beim Abrufen eines JWT-SVID angefordert werden muss, ist immer `https://api.anthropic.com`. Verwende diesen Wert in `jwt_audience` von spiffe-helper, im Workload-API-Aufruf `FetchJWTSVID` und im `audience`-Matcher der Federation Rule.

## SPIRE konfigurieren

Die Anweisungen in diesem Abschnitt sind SPIRE-spezifisch. Wenn du einen anderen SPIFFE-Issuer verwendest, konfiguriere dessen OIDC-Discovery-Endpunkt und den JWT-SVID-Abruf gemäß seiner eigenen Dokumentation und fahre dann bei [Anthropic konfigurieren](https://platform.claude.com/docs/de/manage-claude/wif-providers/spiffe#configure-anthropic) fort.

Wenn du SPIRE bereits mit dem OIDC Discovery Provider betreibst, erfordert die Föderation mit Anthropic auf SPIRE-Seite drei Dinge: einen `jwt_issuer`, der mit der Discovery-URL übereinstimmt, einen Registrierungseintrag für den Workload, der die Claude API aufrufen wird, und eine Möglichkeit für diesen Workload, ein JWT-SVID mit der Anthropic-Audience abzurufen. Die folgenden Unterabschnitte führen durch jeden dieser Punkte. Die Konfigurationsausschnitte zeigen nur die für die Anthropic-Föderation relevanten Einstellungen, keine vollständigen SPIRE-Deployment-Konfigurationen.

<Tip>
  Richtest du SPIRE zum ersten Mal ein? Deploye SPIRE Server und Agent gemäß dem [SPIRE-Quickstart](https://spiffe.io/docs/latest/try/) und füge dann den [OIDC Discovery Provider](https://github.com/spiffe/spire/blob/main/support/oidc-discovery-provider/README.md) als separaten Dienst neben SPIRE Server hinzu. Die Föderation im Discovery-Modus setzt voraus, dass der Provider deployt und öffentlich erreichbar ist. Der Provider ist nicht Teil einer Standard-SPIRE-Installation.
</Tip>

### Den JWT-Issuer überprüfen

Anthropic validiert ein JWT-SVID, indem es dessen `iss`-Claim mit einem registrierten Federation Issuer abgleicht und das JWKS aus dem Discovery-Dokument dieses Issuers abruft. Zwei SPIRE-Einstellungen müssen auf dieselbe URL verweisen: `jwt_issuer` von SPIRE Server (wird zum `iss`-Claim in jedem ausgestellten JWT-SVID) und die `domains`-Liste des OIDC Discovery Providers (bestimmt den Host, von dem das Discovery-Dokument und das JWKS ausgeliefert werden). Diese gemeinsame URL ist das, was du bei Anthropic registrierst.

Die Trust-Domain und die Issuer-URL sind voneinander unabhängig. Die Trust-Domain (`spiffe://prod.example.com`) grenzt den `sub`-Claim ein. Die Issuer-URL (`https://oidc-discovery.prod.example.com`) ist der Ort, von dem Anthropic die Signaturschlüssel abruft. Sie müssen keinen gemeinsamen Hostnamen haben.

Stelle sicher, dass `jwt_issuer` in der Konfiguration von SPIRE Server gesetzt ist und auf die öffentliche URL des Discovery Providers zeigt. Das folgende Beispiel zeigt außerdem eine Standard-Lebensdauer für JWT-SVIDs. Der eingebaute Standardwert von SPIRE beträgt 5 Minuten, was kurz genug ist, dass eine kontinuierliche Rotation erforderlich ist (siehe [spiffe-helper ausführen](https://platform.claude.com/docs/de/manage-claude/wif-providers/spiffe#run-spiffe-helper)). Der Token-Exchange-Endpunkt von Anthropic lehnt jedes Identitätstoken ab, dessen Lebensdauer das konfigurierte Maximum des Federation Issuers überschreitet, das standardmäßig 1 Stunde beträgt (siehe [Validierungsregeln](https://platform.claude.com/docs/de/manage-claude/wif-reference#validation-rules)). Diese Prüfung gilt für jede SPIFFE-Implementierung, nicht nur für SPIRE. Halte daher `default_jwt_svid_ttl` (oder jede eintragsspezifische Überschreibung) auf oder unter diesem Maximum.

```text server.conf
server {
    trust_domain         = "prod.example.com"
    jwt_issuer           = "https://oidc-discovery.prod.example.com"
    default_jwt_svid_ttl = "5m"
    # ...
}
```

In der Konfiguration des OIDC Discovery Providers muss derselbe Hostname unter `domains` erscheinen, und der Provider muss den API-Socket von SPIRE Server erreichen können. Der Provider liefert das Discovery-Dokument und das JWKS über HTTPS aus. Terminiere TLS mit seiner eingebauten ACME-Unterstützung oder schalte einen Load Balancer davor, der dies übernimmt.

```text oidc-discovery-provider.conf
domains = ["oidc-discovery.prod.example.com"]

server_api {
    address = "unix:///run/spire/sockets/private/api.sock"
}

acme {
    email        = "platform@example.com"
    tos_accepted = true
}
```

<Note>
  Das Beispiel verwendet `server_api`, das den Discovery Provider mit dem privilegierten API-Socket von SPIRE Server verbindet. Der Provider akzeptiert auch einen `workload_api`-Block (mit `socket_path` und `trust_domain`), der das Bundle stattdessen über die Workload API eines SPIRE Agents bezieht. Verwende ihn, wenn der Discovery Provider keinen Zugriff auf die Server API haben soll oder auf einem Knoten läuft, der den Server nicht erreichen kann.
</Note>

### Den Workload registrieren

Jeder Workload, der die Claude API aufruft, benötigt einen SPIRE-Registrierungseintrag, der seine Laufzeit-Selektoren einer SPIFFE-ID zuordnet. Wenn der Workload bereits registriert ist, notiere seine SPIFFE-ID, die du im `subject_prefix` der Federation Rule verwendest. Falls nicht, registriere ihn. Für einen Kubernetes-Pod sind die Selektoren typischerweise der Namespace und der Kubernetes-Service-Account:

```bash CLI
# Ersetze NODE_UID durch die UID des Nodes:
#   kubectl get node <node-name> -o jsonpath='{.metadata.uid}'
spire-server entry create \
    -spiffeID spiffe://prod.example.com/ns/inference/sa/worker \
    -parentID spiffe://prod.example.com/spire/agent/k8s_psat/prod-cluster/NODE_UID \
    -selector k8s:ns:inference \
    -selector k8s:sa:worker
```

<Note>
  Die gezeigte `parentID` ist die automatisch generierte Agent-ID eines einzelnen Knotens. Für eine clusterweite Registrierung ordne den Eintrag einem [Node-Alias](https://spiffe.io/docs/latest/deploying/registering/#mapping-workloads-to-multiple-nodes) als Parent zu, sodass er auf Workloads auf jedem Knoten passt, wie es der [SPIRE-Kubernetes-Quickstart](https://spiffe.io/docs/latest/try/getting-started-k8s/) tut.
</Note>

Workloads außerhalb von Kubernetes verwenden Selektoren auf Host-Ebene wie `unix:uid:1000` (`unix:path` ist ebenfalls verfügbar, erfordert aber `discover_workload_path = true` in der Konfiguration des Unix-Workload-Attestors des Agents). Cluster, die [spire-controller-manager](https://github.com/spiffe/spire-controller-manager) ausführen, können Einträge mit der Custom Resource `ClusterSPIFFEID` deklarieren, anstatt `spire-server entry create` direkt aufzurufen.

### spiffe-helper ausführen

[spiffe-helper](https://github.com/spiffe/spiffe-helper) ist ein Sidecar-Hilfsprogramm, das sich mit dem SPIRE-Agent-Socket verbindet, ein JWT-SVID für eine bestimmte Audience abruft, es in eine Datei schreibt und es vor Ablauf erneut abruft. Der Helper läuft standardmäßig im Daemon-Modus. Das folgende Beispiel setzt `daemon_mode = true` explizit.

```text helper.conf
agent_address = "/run/spire/sockets/agent.sock"
# The JWT-SVID file is written under cert_dir
cert_dir      = "/var/run/secrets/anthropic.com"
daemon_mode   = true

jwt_svids = [{
    jwt_audience       = "https://api.anthropic.com"
    jwt_svid_file_name = "token"
}]
```

Führe spiffe-helper in Kubernetes als Sidecar-Container aus, der ein speichergestütztes `emptyDir`-Volume (`medium: Memory`) mit deinem Anwendungscontainer teilt, sodass das Bearer-SVID niemals auf der Festplatte des Knotens landet. Mounte den SPIRE-Agent-Socket vom Host in den Sidecar, mounte das gemeinsame Volume in beiden Containern unter `/var/run/secrets/anthropic.com` und setze `ANTHROPIC_IDENTITY_TOKEN_FILE=/var/run/secrets/anthropic.com/token` im Anwendungscontainer. Auf VMs und Bare Metal führe spiffe-helper als Systemdienst neben dem Workload aus und lass beide auf ein gemeinsames Verzeichnis zeigen.

## Anthropic konfigurieren

Gehe in der Claude Console zur Seite [Workload identity](https://platform.claude.com/settings/workload-identity-federation) (`platform.claude.com/settings/workload-identity-federation`), klicke auf **Connect workload** und wähle **Custom OIDC**. Der Assistent führt dich durch die Registrierung des Issuers, das Erstellen eines Service Accounts und das Erstellen einer Federation Rule.

Der Assistent erstellt diese Ressourcen für dich. Verwende die folgenden Werte, unabhängig davon, ob du sie im Assistenten eingibst oder an die [Admin API](https://platform.claude.com/docs/de/manage-claude/wif-admin-api) sendest:

**Federation Issuer:** Registriere die öffentliche URL des OIDC Discovery Providers im `discovery`-Modus. Anthropic ruft `/.well-known/openid-configuration` von dieser URL ab und folgt der zurückgegebenen `jwks_uri`, um die Signaturschlüssel der Trust-Domain abzurufen.

```json
{
  "name": "spire-prod",
  "issuer_url": "https://oidc-discovery.prod.example.com",
  "jwks": { "type": "discovery" }
}
```

Wenn der Discovery Provider nicht aus dem öffentlichen Internet erreichbar ist, rufe das JWKS selbst ab (`curl https://oidc-discovery.prod.example.com/keys`) und registriere den Issuer mit `"jwks": {"type": "inline", "keys": [...]}` unter Verwendung des Inhalts des zurückgegebenen `keys`-Arrays. Im `inline`-Modus wird die `issuer_url` nur mit dem `iss`-Claim des JWT-SVID verglichen. Anthropic versucht niemals, sie zu erreichen.

<Warning>
  SPIRE rotiert JWT-Signaturschlüssel häufig, standardmäßig im selben Rhythmus wie die CA (`ca_ttl`, 24 Stunden). Wenn du den Issuer mit einem Inline-JWKS statt einer Discovery-URL registrierst, musst du das JWKS bei jeder Rotation von SPIRE aktualisieren: Füge den neuen Schlüssel hinzu, bevor Workloads beginnen, ihn vorzulegen, und **entferne abgelöste Schlüssel**, sobald die mit ihnen signierten Tokens abgelaufen sind. Veraltete Schlüssel, die in einem Inline-JWKS verbleiben, bleiben unbegrenzt vertrauenswürdig.
</Warning>

Um JWKS-Aktualisierungen zu automatisieren, ohne einen öffentlichen Discovery-Endpunkt bereitzustellen, konfiguriere ein [BundlePublisher](https://spiffe.io/docs/latest/deploying/spire_server/#built-in-plugins)-Plugin von SPIRE Server (`aws_s3`, `gcp_cloudstorage` oder `k8s_configmap`) mit `format = "jwks"`, um die JWT-Signaturschlüssel bei jeder Rotation in einen externen Speicher zu übertragen, und aktualisiere dann die Inline-Schlüssel des Issuers über die [Admin API](https://platform.claude.com/docs/de/manage-claude/wif-admin-api#federation-issuers).

**Federation Rule:** Gleiche den `sub` des JWT-SVID (die SPIFFE-ID) und die `aud` ab, die du spiffe-helper anfordern lässt. SPIFFE-IDs sind URI-Strings, und `subject_prefix` gleicht sie als opaken Text ab, sodass sowohl ein exakter Wert als auch ein Präfix-Match mit abschließendem `*` funktionieren. Für komplexere Muster verwende eine CEL-`condition`.

```json
{
  "name": "spire-inference-worker",
  "issuer_id": "fdis_...",
  "match": {
    "subject_prefix": "spiffe://prod.example.com/ns/inference/sa/worker",
    "audience": "https://api.anthropic.com"
  },
  "target": {
    "type": "service_account",
    "service_account_id": "svac_..."
  },
  "workspace_id": "wrkspc_...",
  "oauth_scope": "workspace:developer",
  "token_lifetime_seconds": 600
}
```

`token_lifetime_seconds` ist die Lebensdauer des Anthropic-Access-Tokens, das der Austausch zurückgibt, nicht die des JWT-SVID. Das SDK erneuert das Access-Token automatisch.

Sei so spezifisch, wie der Workload es zulässt. Lockere `subject_prefix` nur dann auf `spiffe://prod.example.com/ns/inference/*`, wenn jeder unter diesem Pfad registrierte Workload demselben Anthropic-Service-Account zugeordnet werden soll. Füge die `fdrl_...`-ID der Regel zur Umgebungsvariable `ANTHROPIC_FEDERATION_RULE_ID` des Workloads hinzu.

## Token abrufen und verwenden

Das Claude SDK kann das JWT-SVID aus der Datei lesen, die spiffe-helper pflegt, oder – außer in Java – die SPIFFE Workload API direkt über einen Token-Provider aufrufen. Der Dateipfad ist die einfachste Integration und funktioniert in jeder SDK-Sprache. Der Token-Provider-Weg macht den Sidecar überflüssig, erfordert aber einen SPIFFE-Workload-API-Client in der Sprache deiner Anwendung.

<Tabs>
  <Tab title="Dateibasiert mit spiffe-helper">
    Wenn spiffe-helper ein frisches JWT-SVID nach `/var/run/secrets/anthropic.com/token` schreibt, setze `ANTHROPIC_IDENTITY_TOKEN_FILE` auf diesen Pfad zusammen mit `ANTHROPIC_FEDERATION_RULE_ID`, `ANTHROPIC_ORGANIZATION_ID`, `ANTHROPIC_SERVICE_ACCOUNT_ID` und `ANTHROPIC_WORKSPACE_ID`. Das SDK liest die Datei bei jedem Token-Austausch, sodass es immer das zuletzt rotierte SVID verwendet, und erneuert das Anthropic-Access-Token automatisch, bevor es abläuft. Siehe [Umgebungsvariablen](https://platform.claude.com/docs/de/manage-claude/wif-reference#environment-variables), um zu erfahren, woher jeder Wert stammt.

    <CodeGroup>
      ```bash cURL
      JWT=$(cat "$ANTHROPIC_IDENTITY_TOKEN_FILE")

      ACCESS_TOKEN=$(curl -sS https://api.anthropic.com/v1/oauth/token \
        -H "content-type: application/json" \
        --data @- <<JSON | jq -r .access_token
      {
        "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
        "assertion": "$JWT",
        "federation_rule_id": "$ANTHROPIC_FEDERATION_RULE_ID",
        "organization_id": "$ANTHROPIC_ORGANIZATION_ID",
        "service_account_id": "$ANTHROPIC_SERVICE_ACCOUNT_ID",
        "workspace_id": "$ANTHROPIC_WORKSPACE_ID"
      }
      JSON
      )

      curl https://api.anthropic.com/v1/messages \
        -H "authorization: Bearer $ACCESS_TOKEN" \
        -H "anthropic-version: 2023-06-01" \
        -H "content-type: application/json" \
        -d '{
          "model": "claude-opus-5-5",
          "max_tokens": 1024,
          "messages": [{"role": "user", "content": "Hello, Claude"}]
        }' | jq -r '.content[] | select(.type == "text") | .text'
      ```

      ```bash CLI
      # Liest das JWT-SVID, das spiffe-helper schreibt nach
      # ANTHROPIC_IDENTITY_TOKEN_FILE, sowie ANTHROPIC_FEDERATION_RULE_ID,
      # ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID und ANTHROPIC_WORKSPACE_ID.
      ant messages create \
        --model claude-opus-5-5 \
        --max-tokens 1024 \
        --message '{role: user, content: "Hello, Claude"}'
      ```

      ```python Python
      import anthropic

      # Liest das JWT-SVID, das spiffe-helper schreibt nach
      # ANTHROPIC_IDENTITY_TOKEN_FILE, sowie ANTHROPIC_FEDERATION_RULE_ID,
      # ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID und ANTHROPIC_WORKSPACE_ID.
      client = anthropic.Anthropic()

      message = client.messages.create(
          model="claude-opus-5-5",
          max_tokens=1024,
          messages=[{"role": "user", "content": "Hello, Claude"}],
      )
      print(next(block.text for block in message.content if block.type == "text"))
      ```

      ```typescript TypeScript
      import Anthropic from "@anthropic-ai/sdk";

      // Liest das JWT-SVID, das spiffe-helper schreibt nach
      // ANTHROPIC_IDENTITY_TOKEN_FILE, sowie ANTHROPIC_FEDERATION_RULE_ID,
      // ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID und ANTHROPIC_WORKSPACE_ID.
      const client = new Anthropic();

      const message = await client.messages.create({
        model: "claude-opus-5-5",
        max_tokens: 1024,
        messages: [{ role: "user", content: "Hello, Claude" }]
      });
      for (const block of message.content) {
        if (block.type === "text") {
          console.log(block.text);
        }
      }
      ```

      ```csharp C#
      // Liest das JWT-SVID, das spiffe-helper schreibt nach
      // ANTHROPIC_IDENTITY_TOKEN_FILE, sowie ANTHROPIC_FEDERATION_RULE_ID,
      // ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID und ANTHROPIC_WORKSPACE_ID.
      using var client = new AnthropicClient();

      var message = await client.Messages.Create(new()
      {
          Model = Model.ClaudeOpus5_5,
          MaxTokens = 1024,
          Messages = [new() { Role = Role.User, Content = "Hello, Claude" }],
      });
      foreach (var block in message.Content)
      {
          if (block.Value is TextBlock textBlock)
          {
              Console.WriteLine(textBlock.Text);
          }
      }
      ```

      ```go Go
      // Liest das JWT-SVID, das spiffe-helper schreibt nach
      // ANTHROPIC_IDENTITY_TOKEN_FILE, sowie ANTHROPIC_FEDERATION_RULE_ID,
      // ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID und ANTHROPIC_WORKSPACE_ID.
      client := anthropic.NewClient()

      message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
      	Model:     anthropic.ModelClaudeOpus5_5,
      	MaxTokens: 1024,
      	Messages: []anthropic.MessageParam{
      		anthropic.NewUserMessage(anthropic.NewTextBlock("Hello, Claude")),
      	},
      })
      if err != nil {
      	panic(err)
      }
      for _, block := range message.Content {
      	if textBlock, ok := block.AsAny().(anthropic.TextBlock); ok {
      		fmt.Println(textBlock.Text)
      		break
      	}
      }
      ```

      ```java Java
      // Liest das JWT-SVID, das spiffe-helper schreibt nach
      // ANTHROPIC_IDENTITY_TOKEN_FILE, sowie ANTHROPIC_FEDERATION_RULE_ID,
      // ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID und ANTHROPIC_WORKSPACE_ID.
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      var message = client.messages().create(MessageCreateParams.builder()
              .model(Model.CLAUDE_OPUS_5_5)
              .maxTokens(1024)
              .addUserMessage("Hello, Claude")
              .build());

      IO.println(message.content());
      ```

      ```php PHP
      use Anthropic\Client;

      // Liest das JWT-SVID, das spiffe-helper schreibt nach
      // ANTHROPIC_IDENTITY_TOKEN_FILE, sowie ANTHROPIC_FEDERATION_RULE_ID,
      // ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID und ANTHROPIC_WORKSPACE_ID.
      $client = new Client();

      $message = $client->messages->create(
          model: 'claude-opus-5-5',
          maxTokens: 1024,
          messages: [['role' => 'user', 'content' => 'Hello, Claude']],
      );
      $textBlock = array_find($message->content, static fn ($block): bool => $block->type === 'text');
      echo $textBlock->text, PHP_EOL;
      ```

      ```ruby Ruby
      require "anthropic"

      # Liest das JWT-SVID, das spiffe-helper schreibt nach
      # ANTHROPIC_IDENTITY_TOKEN_FILE, sowie ANTHROPIC_FEDERATION_RULE_ID,
      # ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID und ANTHROPIC_WORKSPACE_ID.
      client = Anthropic::Client.new

      message = client.messages.create(
        model: "claude-opus-5-5",
        max_tokens: 1024,
        messages: [{role: "user", content: "Hello, Claude"}]
      )
      puts message.content.find { it.type == :text }.text
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Token-Provider über die SPIFFE Workload API">
    Außer in Java können Workloads, die einen SPIFFE-Workload-API-Client direkt einbinden, spiffe-helper überspringen und dem SDK einen Token-Provider übergeben, der ein frisches JWT-SVID vom Agent-Socket abruft. Das SDK ruft den Provider vor jedem Token-Austausch auf, sodass der Workload immer ein nicht abgelaufenes SVID vorlegt. Python ([py-spiffe](https://github.com/HewlettPackard/py-spiffe)) und Go ([go-spiffe](https://github.com/spiffe/go-spiffe)) verfügen über ausgereifte Workload-API-Clients.

    <CodeGroup exclude="shell, typescript, java, csharp, php, ruby">
      ```python Python
      import os
      import anthropic
      from anthropic import WorkloadIdentityCredentials
      from spiffe import JwtSource

      AUDIENCE = "https://api.anthropic.com"

      # Verbindet sich mit dem SPIRE-Agent-Socket unter SPIFFE_ENDPOINT_SOCKET.
      jwt_source = JwtSource()


      def fetch_jwt_svid() -> str:
          svid = jwt_source.fetch_svid(audience={AUDIENCE})  # audience is a set of strings
          return svid.token


      client = anthropic.Anthropic(
          credentials=WorkloadIdentityCredentials(
              identity_token_provider=fetch_jwt_svid,
              federation_rule_id=os.environ["ANTHROPIC_FEDERATION_RULE_ID"],
              organization_id=os.environ["ANTHROPIC_ORGANIZATION_ID"],
              service_account_id=os.environ["ANTHROPIC_SERVICE_ACCOUNT_ID"],
              workspace_id=os.environ.get("ANTHROPIC_WORKSPACE_ID"),
          ),
      )

      message = client.messages.create(
          model="claude-opus-5-5",
          max_tokens=1024,
          messages=[{"role": "user", "content": "Hello, Claude"}],
      )
      print(next(block.text for block in message.content if block.type == "text"))
      ```

      ```go Go
      import (
      	"context"
      	"fmt"
      	"os"

      	"github.com/anthropics/anthropic-sdk-go"
      	"github.com/anthropics/anthropic-sdk-go/option"
      	"github.com/spiffe/go-spiffe/v2/svid/jwtsvid"
      	"github.com/spiffe/go-spiffe/v2/workloadapi"
      )
      // ...
      	const audience = "https://api.anthropic.com"

      	ctx := context.Background()
      	source, err := workloadapi.NewJWTSource(ctx)
      	if err != nil {
      		panic(err)
      	}
      	defer source.Close()

      	fetchJWTSVID := func(ctx context.Context) (string, error) {
      		svid, err := source.FetchJWTSVID(ctx, jwtsvid.Params{Audience: audience})
      		if err != nil {
      			return "", err
      		}
      		return svid.Marshal(), nil
      	}

      	client := anthropic.NewClient(
      		option.WithFederationTokenProvider(fetchJWTSVID, option.FederationOptions{
      			FederationRuleID: os.Getenv("ANTHROPIC_FEDERATION_RULE_ID"),
      			OrganizationID:   os.Getenv("ANTHROPIC_ORGANIZATION_ID"),
      			ServiceAccountID: os.Getenv("ANTHROPIC_SERVICE_ACCOUNT_ID"),
      			WorkspaceID:      os.Getenv("ANTHROPIC_WORKSPACE_ID"),
      		}),
      	)

      	message, err := client.Messages.New(ctx, anthropic.MessageNewParams{
      		Model:     anthropic.ModelClaudeOpus5_5,
      		MaxTokens: 1024,
      		Messages: []anthropic.MessageParam{
      			anthropic.NewUserMessage(anthropic.NewTextBlock("Hello, Claude")),
      		},
      	})
      	if err != nil {
      		panic(err)
      	}
      	for _, block := range message.Content {
      		if textBlock, ok := block.AsAny().(anthropic.TextBlock); ok {
      			fmt.Println(textBlock.Text)
      			break
      		}
      	}
      ```
    </CodeGroup>

    <Note>
      Für andere Sprachen rufe das JWT-SVID mit dem SPIFFE-Workload-API-Client deiner Laufzeitumgebung ab (oder rufe `spire-agent api fetch jwt` per Shell auf), schreibe es in eine Datei und setze `ANTHROPIC_IDENTITY_TOKEN_FILE` auf diesen Pfad wie im dateibasierten Tab.
    </Note>
  </Tab>
</Tabs>

## Das Setup überprüfen

Bevor du das SDK einbindest, rufe ein JWT-SVID direkt von SPIRE Agent ab und bestätige, dass die Claims dem entsprechen, was deine Federation Rule erwartet. Wenn du eine andere SPIFFE-Implementierung verwendest, rufe ein JWT-SVID mit deren CLI oder Workload-API-Client ab und dekodiere die Payload auf dieselbe Weise.

<Note>
  Die Workload API attestiert den aufrufenden Prozess. Für einen Kubernetes-Registrierungseintrag führe diesen Befehl innerhalb eines Pods aus, der die Selektoren des Eintrags erfüllt und den Agent-Socket gemountet hat (zum Beispiel mit `kubectl exec`). Auf VMs und Bare Metal führe ihn als der Benutzer oder Prozess aus, der den `unix:`-Selektoren des Eintrags entspricht. Die Ausführung aus einer nicht attestierten Host-Shell gibt `no identity issued` zurück, was der häufigste Fehler im Überprüfungsschritt ist.
</Note>

```bash CLI
spire-agent api fetch jwt \
    -audience https://api.anthropic.com \
    -socketPath /run/spire/sockets/agent.sock \
    -output json \
  | jq -r '.[0].svids[0].svid' \
  | jq -rR 'split(".")[1] | gsub("-";"+") | gsub("_";"/") | @base64d | fromjson'
```

Das Flag `-output json` gibt die SVID-Antwort und die Bundle-Antwort als JSON-Array mit zwei Elementen zurück, sodass `jq -r '.[0].svids[0].svid'` das reine Token extrahiert. Bei älteren SPIRE-Versionen ohne `-output` gibt der Befehl stattdessen einen beschrifteten Block aus. Leite in diesem Fall die Standardausgabe durch `awk '/^[[:space:]]*eyJ/{print $1; exit}'`, um die Token-Zeile zu extrahieren. Prüfe, dass `iss` die von dir registrierte URL des OIDC Discovery Providers ist, `sub` die SPIFFE-ID des Workloads ist und `aud` den Wert `https://api.anthropic.com` enthält. Führe dann das cURL-Beispiel aus [Token abrufen und verwenden](https://platform.claude.com/docs/de/manage-claude/wif-providers/spiffe#acquire-and-use-the-token) aus. Ein erfolgreicher Austausch gibt ein `access_token` zurück, das mit `sk-ant-oat01-` beginnt. Wenn der Austausch mit der opaken `401`-`authentication_error`-Antwort (Meldung `Authentication failed`) fehlschlägt, prüfe die [Seite mit dem Authentifizierungsverlauf](https://platform.claude.com/settings/workload-identity-federation?tab=history) in der Claude Console auf den Ablehnungsgrund und siehe [Einen fehlgeschlagenen Austausch beheben](https://platform.claude.com/docs/de/manage-claude/wif-reference#troubleshoot-a-failed-exchange). Die häufigste Ursache auf SPIRE-Seite ist eine Abweichung zwischen dem `jwt_issuer` von SPIRE Server und der als Federation Issuer registrierten URL.

## Deine Regel eingrenzen

Die Pfadkonventionen für SPIFFE-IDs werden vom Betreiber festgelegt, daher sollte der `subject_prefix`-Matcher der Federation Rule das Pfadschema widerspiegeln, das deine Registrierungseinträge verwenden. Gängige Schemata sind `spiffe://<trust-domain>/ns/<namespace>/sa/<service-account>` (der Standard, den die `ClusterSPIFFEID`-Ressource in spire-controller-manager ausgibt) und `spiffe://<trust-domain>/host/<hostname>/<service>` für VM- und Bare-Metal-Workloads.

<Warning>
  Ein `subject_prefix` von `spiffe://prod.example.com/*` passt auf jeden Workload in der Trust-Domain. Ohne einen `audience`-Matcher akzeptiert die Regel außerdem JWT-SVIDs, die für eine beliebige Audience ausgestellt wurden, einschließlich solcher, die der Workload für nicht verwandte Relying Parties angefordert hat.
</Warning>

Beschränke den `match`-Block der Regel auf den engsten Geltungsbereich, der zu deinem Anwendungsfall passt:

* **Auf einen Workload festlegen:** Setze `subject_prefix` auf die vollständige SPIFFE-ID ohne abschließendes `*`.
* **Immer eine Audience setzen:** Verlange `audience` in der Regel und konfiguriere spiffe-helper (oder den Workload-API-Aufruf) mit demselben Wert, sodass für andere Relying Parties ausgestellte SVIDs abgelehnt werden.
* **Nach Pfadsegment eingrenzen:** Verwende `spiffe://prod.example.com/ns/inference/*`, um jedem unter einem Namespace registrierten Workload Zugriff zu gewähren, und erstelle pro Namespace eine separate Regel und einen separaten Anthropic-Service-Account, anstatt eine Regel auszuweiten.
* **Ein Issuer pro Trust-Domain:** Jede SPIRE-Trust-Domain hat ihre eigenen Signaturschlüssel und ihren eigenen OIDC Discovery Provider. Registriere jede als separaten Federation Issuer und binde Regeln an den Issuer, dem die SPIFFE-IDs gehören, auf die sie passen.

## Nächste Schritte

<CardGroup cols={2}>
  <Card title="WIF mit Okta verwenden" icon="lock" href="https://platform.claude.com/docs/de/manage-claude/wif-providers/okta">
    Föderiere Identitäten von Okta-Service-Anwendungen mit Workload Identity Federation zur Claude API.
  </Card>

  <Card title="Workload Identity Federation" icon="cloud" href="https://platform.claude.com/docs/de/manage-claude/workload-identity-federation">
    Authentifiziere Workloads gegenüber der Claude API mit kurzlebigen Identitätstokens von deinem eigenen Identity Provider anstelle langlebiger statischer API-Keys.
  </Card>

  <Card title="WIF-Referenz" icon="book" href="https://platform.claude.com/docs/de/manage-claude/wif-reference">
    Umgebungsvariablen, Validierungsregeln, Profilkonfiguration und Fehlerreferenz für Workload Identity Federation.
  </Card>

  <Card title="WIF mit Kubernetes verwenden" icon="cube" href="https://platform.claude.com/docs/de/manage-claude/wif-providers/kubernetes">
    Authentifiziere dich gegenüber der Claude API aus selbstverwalteten Kubernetes-Clustern mithilfe projizierter Service-Account-Tokens.
  </Card>
</CardGroup>
