Ogni esecuzione di un workflow di GitHub Actions può richiedere un token di identità firmato dall'issuer ospitato da GitHub all'indirizzo https://token.actions.githubusercontent.com. Con la Workload Identity Federation, il tuo workflow scambia quel token con un token di accesso Anthropic a breve durata, così i tuoi job di CI possono chiamare la Claude API senza un segreto ANTHROPIC_API_KEY memorizzato nel tuo repository.
Il claim sub del token codifica il repository e il contesto del trigger. Per un push su un branch ha la forma repo:<owner>/<repo>:ref:refs/heads/<branch>. Le esecuzioni da pull request usano repo:<owner>/<repo>:pull_request, e i deployment controllati da environment usano repo:<owner>/<repo>:environment:<name>. La tua regola di federazione effettua il match su questo claim (e su altri, come repository_owner e ref) per decidere quali esecuzioni di workflow sono autorizzate ad autenticarsi.
id-token: write.GitHub emette un token di identità solo per i job che lo richiedono esplicitamente. Aggiungi il permesso id-token: write a livello di workflow o di job:
permissions:
id-token: write
contents: readAll'interno del job, il runner espone due variabili d'ambiente: ACTIONS_ID_TOKEN_REQUEST_URL e ACTIONS_ID_TOKEN_REQUEST_TOKEN. Chiama l'URL di richiesta con il token di richiesta come credenziale bearer e l'audience scelta come parametro di query, quindi scrivi il JSON Web Token (JWT) restituito in un file:
- 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-jwtSe preferisci JavaScript, actions/github-script espone la stessa funzionalità tramite core.getIDToken(audience):
- 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);Il token decodificato contiene claim che descrivono l'esecuzione del workflow. La tua regola di federazione effettua il match su questi:
{
"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"
}Consulta il riferimento di GitHub sui subject claim OIDC per l'elenco completo dei formati di sub.
Nella Claude Console, apri Settings → Workload identity, fai clic su Connect workload e seleziona il riquadro GitHub Actions. La procedura guidata ti accompagna nella registrazione dell'issuer, nella creazione di un service account e nella creazione di una regola di federazione.
La procedura guidata crea queste risorse per te. Usa i seguenti valori sia che tu li inserisca nella procedura guidata sia che li invii all'Admin API:
Federation issuer: GitHub pubblica il suo documento di discovery OIDC e il JWKS pubblicamente, quindi usa la modalità discovery. Anthropic aggiorna le chiavi automaticamente quando GitHub le ruota.
{
"name": "github-actions",
"issuer_url": "https://token.actions.githubusercontent.com",
"jwks": { "type": "discovery" }
}Regola di federazione: Effettua il match solo sulle esecuzioni di workflow di cui intendi fidarti. Consulta Limita quali workflow possono autenticarsi per sapere come delimitare questi claim in modo sicuro.
{
"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
}Sii il più specifico possibile per quanto consentito dal workload. Allenta subject_prefix a repo:your-org/your-repo:* (abbinato a un vincolo claims.ref) solo se la regola deve corrispondere a più tipi di evento dello stesso repository, perché il segmento finale di sub varia tra gli eventi ref:..., environment:... e pull_request.
Imposta le variabili d'ambiente di federazione sul job e chiama l'SDK normalmente. Anthropic() legge ANTHROPIC_IDENTITY_TOKEN_FILE, scambia il JWT alla prima richiesta e aggiorna automaticamente il token di accesso prima che scada.
import anthropic
# Legge ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID,
# ANTHROPIC_SERVICE_ACCOUNT_ID, ANTHROPIC_WORKSPACE_ID e ANTHROPIC_IDENTITY_TOKEN_FILE
# dall'ambiente del job.
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"))Ogni token di identità emesso da GitHub scade circa cinque minuti dopo l'emissione. L'endpoint di richiesta del token (ACTIONS_ID_TOKEN_REQUEST_URL) rimane valido per l'intero job, quindi puoi recuperare un token nuovo in qualsiasi momento. L'SDK scambia il token al primo utilizzo e memorizza nella cache il token di accesso Anthropic risultante. Per i job che durano più a lungo della durata del token Anthropic, l'SDK rilegge ANTHROPIC_IDENTITY_TOKEN_FILE a ogni aggiornamento, quindi riesegui periodicamente lo step di recupero (o inseriscilo in un loop in background) per mantenere il file aggiornato. In alternativa, passa all'SDK una callback token-provider che chiami direttamente ACTIONS_ID_TOKEN_REQUEST_URL invece di usare il percorso del file.
Uno scambio riuscito restituisce un access_token che inizia con sk-ant-oat01- e un valore expires_in in secondi. In caso di 400 invalid_grant, consulta Risolvere i problemi di uno scambio non riuscito; la causa più comune lato GitHub Actions è il formato del claim sub che non corrisponde (il suo segmento finale varia tra gli eventi ref:..., environment:... e pull_request).
Un subject_prefix di repo:your-org/* da solo corrisponde a ogni repository della tua organizzazione e, senza un vincolo ref, corrisponde anche alle esecuzioni pull_request attivate da fork. Chiunque possa aprire una pull request verso un repository corrispondente potrebbe ottenere un token Anthropic federato.
Blocca il blocco match della regola all'ambito più ristretto adatto al tuo caso d'uso:
subject_prefix: "repo:your-org/your-repo:*" in modo che gli altri repository dell'organizzazione non corrispondano."ref": "refs/heads/main" (o il tuo branch di release) sotto claims in modo che le esecuzioni da pull request e i feature branch non corrispondano."repository_owner": "your-org" sotto claims come controllo di difesa in profondità contro i casi limite di parsing di sub.subject_prefix: "repo:your-org/your-repo:environment:production" e proteggi quell'environment con revisori obbligatori in GitHub.Was this page helpful?