Jeder GitHub Actions-Workflow-Lauf kann ein signiertes Identitätstoken vom gehosteten Issuer von GitHub unter https://token.actions.githubusercontent.com anfordern. Mit Workload Identity Federation tauscht dein Workflow dieses Token gegen ein kurzlebiges Anthropic-Zugriffstoken aus, sodass deine CI-Jobs die Claude API aufrufen können, ohne dass ein ANTHROPIC_API_KEY-Secret in deinem Repository gespeichert ist.
Der sub-Claim des Tokens kodiert das Repository und den Trigger-Kontext. Für einen Push auf einen Branch hat er die Form repo:<owner>/<repo>:ref:refs/heads/<branch>. Pull-Request-Läufe verwenden repo:<owner>/<repo>:pull_request, und Environment-gesteuerte Deployments verwenden repo:<owner>/<repo>:environment:<name>. Deine Federation-Regel gleicht diesen Claim (und andere, wie repository_owner und ref) ab, um zu entscheiden, welche Workflow-Läufe sich authentifizieren dürfen.
id-token: write erteilen kannst.GitHub stellt ein Identitätstoken nur für Jobs aus, die es explizit anfordern. Füge die Berechtigung id-token: write auf Workflow- oder Job-Ebene hinzu:
permissions:
id-token: write
contents: readInnerhalb des Jobs stellt der Runner zwei Umgebungsvariablen bereit: ACTIONS_ID_TOKEN_REQUEST_URL und ACTIONS_ID_TOKEN_REQUEST_TOKEN. Rufe die Request-URL mit dem Request-Token als Bearer-Credential und deiner gewählten Audience als Query-Parameter auf und schreibe dann das zurückgegebene JSON Web Token (JWT) in eine Datei:
- name: Fetch GitHub OIDC token
run: |
curl -sS -H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=https://api.anthropic.com" \
| jq -r .value > /tmp/gha-jwtWenn du JavaScript bevorzugst, stellt actions/github-script dieselbe Funktionalität über core.getIDToken(audience) bereit:
- name: Fetch GitHub OIDC token
uses: actions/github-script@v8
with:
script: |
const fs = require('fs');
const token = await core.getIDToken('https://api.anthropic.com');
fs.writeFileSync('/tmp/gha-jwt', token);Das dekodierte Token enthält Claims, die den Workflow-Lauf beschreiben. Deine Federation-Regel gleicht diese ab:
{
"iss": "https://token.actions.githubusercontent.com",
"sub": "repo:your-org/your-repo:ref:refs/heads/main",
"aud": "https://api.anthropic.com",
"repository": "your-org/your-repo",
"repository_owner": "your-org",
"ref": "refs/heads/main",
"sha": "abc123...",
"workflow": "CI",
"actor": "octocat",
"event_name": "push"
}Siehe GitHubs Referenz zu OIDC-Subject-Claims für die vollständige Liste der sub-Formate.
Öffne in der Claude Console Settings → Workload identity, klicke auf Connect workload und wähle die Kachel GitHub Actions aus. Der Assistent führt dich durch die Registrierung des Issuers, die Erstellung eines Service Accounts und die Erstellung einer Federation-Regel.
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 sendest:
Federation Issuer: GitHub veröffentlicht sein OIDC-Discovery-Dokument und JWKS öffentlich, verwende daher den Discovery-Modus. Anthropic aktualisiert die Schlüssel automatisch, wenn GitHub sie rotiert.
{
"name": "github-actions",
"issuer_url": "https://token.actions.githubusercontent.com",
"jwks": { "type": "discovery" }
}Federation-Regel: Gleiche nur die Workflow-Läufe ab, denen du vertrauen möchtest. Siehe Einschränken, welche Workflows sich authentifizieren können, um zu erfahren, wie du diese Claims sicher eingrenzt.
{
"name": "gha-main",
"issuer_id": "fdis_...",
"match": {
"subject_prefix": "repo:your-org/your-repo:ref:refs/heads/main",
"audience": "https://api.anthropic.com",
"claims": {
"repository_owner": "your-org"
}
},
"target": {
"type": "service_account",
"service_account_id": "svac_..."
},
"workspace_id": "wrkspc_...",
"oauth_scope": "workspace:developer",
"token_lifetime_seconds": 600
}Sei so spezifisch, wie es der Workload erlaubt. Lockere subject_prefix nur dann auf repo:your-org/your-repo:* (gepaart mit einer claims.ref-Einschränkung), wenn die Regel mehrere Event-Typen aus demselben Repository abgleichen muss, da das letzte Segment von sub zwischen ref:...-, environment:...- und pull_request-Events variiert.
Setze die Federation-Umgebungsvariablen für den Job und rufe das SDK wie gewohnt auf. Anthropic() liest ANTHROPIC_IDENTITY_TOKEN_FILE, tauscht das JWT bei der ersten Anfrage aus und aktualisiert das Zugriffstoken automatisch, bevor es abläuft.
import anthropic
# Liest ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID,
# ANTHROPIC_SERVICE_ACCOUNT_ID, ANTHROPIC_WORKSPACE_ID und ANTHROPIC_IDENTITY_TOKEN_FILE
# aus der Job-Umgebung.
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(next(block.text for block in message.content if block.type == "text"))Jedes von GitHub ausgestellte Identitätstoken läuft etwa fünf Minuten nach der Ausstellung ab. Der Token-Request-Endpunkt (ACTIONS_ID_TOKEN_REQUEST_URL) bleibt für den gesamten Job gültig, sodass du jederzeit ein frisches Token abrufen kannst. Das SDK tauscht das Token bei der ersten Verwendung aus und cached das resultierende Anthropic-Zugriffstoken. Für Jobs, die länger laufen als die Lebensdauer des Anthropic-Tokens, liest das SDK ANTHROPIC_IDENTITY_TOKEN_FILE bei jeder Aktualisierung erneut ein. Führe den Abrufschritt daher regelmäßig erneut aus (oder verpacke ihn in eine Hintergrundschleife), um die Datei aktuell zu halten. Alternativ kannst du dem SDK einen Token-Provider-Callback übergeben, der ACTIONS_ID_TOKEN_REQUEST_URL direkt aufruft, anstatt den Dateipfad zu verwenden.
Ein erfolgreicher Austausch gibt ein access_token zurück, das mit sk-ant-oat01- beginnt, sowie einen expires_in-Wert in Sekunden. Bei 400 invalid_grant siehe Fehlerbehebung bei einem fehlgeschlagenen Austausch; die häufigste Ursache auf GitHub Actions-Seite ist, dass das Format des sub-Claims nicht übereinstimmt (sein letztes Segment variiert zwischen ref:...-, environment:...- und pull_request-Events).
Ein subject_prefix von repo:your-org/* allein passt auf jedes Repository in deiner Organisation, und ohne eine ref-Einschränkung passt er auch auf pull_request-Läufe, die von Forks ausgelöst werden. Jeder, der einen Pull Request gegen ein passendes Repository öffnen kann, könnte ein föderiertes Anthropic-Token erhalten.
Beschränke den match-Block der Regel auf den engsten Geltungsbereich, der zu deinem Anwendungsfall passt:
subject_prefix: "repo:your-org/your-repo:*", damit andere Repositories in der Organisation nicht übereinstimmen."ref": "refs/heads/main" (oder deinen Release-Branch) unter claims hinzu, damit Pull-Request-Läufe und Feature-Branches nicht übereinstimmen."repository_owner": "your-org" unter claims als Defense-in-Depth-Prüfung gegen Randfälle beim Parsen von sub hinzu.subject_prefix: "repo:your-org/your-repo:environment:production" ab und sichere diese Umgebung mit erforderlichen Reviewern in GitHub ab.Was this page helpful?