Cada execução de workflow do GitHub Actions pode solicitar um token de identidade assinado do emissor hospedado do GitHub em https://token.actions.githubusercontent.com. Com o Workload Identity Federation, seu workflow troca esse token por um token de acesso de curta duração da Anthropic, para que seus jobs de CI possam chamar a API do Claude sem um segredo ANTHROPIC_API_KEY armazenado no seu repositório.
A claim sub do token codifica o repositório e o contexto do gatilho. Para um push em uma branch, ela tem o formato repo:<owner>/<repo>:ref:refs/heads/<branch>. Execuções de pull request usam repo:<owner>/<repo>:pull_request, e deployments controlados por ambiente usam repo:<owner>/<repo>:environment:<name>. Sua regra de federação faz a correspondência com essa claim (e outras, como repository_owner e ref) para decidir quais execuções de workflow têm permissão para se autenticar.
id-token: write.O GitHub só emite um token de identidade para jobs que o solicitam explicitamente. Adicione a permissão id-token: write no nível do workflow ou do job:
permissions:
id-token: write
contents: readDentro do job, o runner expõe duas variáveis de ambiente: ACTIONS_ID_TOKEN_REQUEST_URL e ACTIONS_ID_TOKEN_REQUEST_TOKEN. Chame a URL de solicitação usando o token de solicitação como credencial bearer e a audiência escolhida como parâmetro de query, depois grave o "JSON Web Token" (JWT) retornado em um arquivo:
- 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 preferir JavaScript, actions/github-script expõe a mesma funcionalidade através de 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);O token decodificado contém claims que descrevem a execução do workflow. Sua regra de federação faz a correspondência com elas:
{
"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"
}Consulte a referência de claims de subject OIDC do GitHub para a lista completa de formatos de sub.
Siga o passo a passo de configuração para registrar um emissor de federação, criar uma conta de serviço da Anthropic e criar uma regra de federação no Claude Console. Use estes valores específicos do GitHub Actions.
Emissor de federação: o GitHub publica seu documento de descoberta OIDC e JWKS publicamente, então use o modo de descoberta. A Anthropic atualiza as chaves automaticamente quando o GitHub as rotaciona.
{
"name": "github-actions",
"issuer_url": "https://token.actions.githubusercontent.com",
"jwks_source": "discovery"
}Regra de federação: faça a correspondência apenas com as execuções de workflow que você pretende confiar. Consulte Restringir quais workflows podem se autenticar para saber como delimitar essas claims com segurança.
{
"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
}Seja tão específico quanto a carga de trabalho permitir. Afrouxe subject_prefix para repo:your-org/your-repo:* (combinado com uma restrição claims.ref) apenas se a regra precisar corresponder a vários tipos de evento do mesmo repositório, já que o segmento final de sub varia entre eventos ref:..., environment:... e pull_request.
Defina as variáveis de ambiente de federação no job e chame o SDK normalmente. Anthropic() lê ANTHROPIC_IDENTITY_TOKEN_FILE, troca o JWT na primeira requisição e atualiza o token de acesso automaticamente antes que ele expire.
import anthropic
# Lê ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID,
# ANTHROPIC_SERVICE_ACCOUNT_ID, ANTHROPIC_WORKSPACE_ID e ANTHROPIC_IDENTITY_TOKEN_FILE
# do ambiente do job.
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(message.content[0].text)Cada token de identidade emitido pelo GitHub expira aproximadamente cinco minutos após a emissão. O endpoint de solicitação de token (ACTIONS_ID_TOKEN_REQUEST_URL) permanece válido durante todo o job, então você pode obter um token novo a qualquer momento. O SDK troca o token no primeiro uso e armazena em cache o token de acesso da Anthropic resultante. Para jobs que duram mais do que o tempo de vida do token da Anthropic, o SDK relê ANTHROPIC_IDENTITY_TOKEN_FILE a cada atualização, então execute novamente o passo de obtenção periodicamente (ou encapsule-o em um loop em segundo plano) para manter o arquivo atualizado. Como alternativa, passe um callback provedor de token para o SDK que chame ACTIONS_ID_TOKEN_REQUEST_URL diretamente em vez de usar o caminho do arquivo.
Uma troca bem-sucedida retorna um access_token começando com sk-ant-oat01- e um valor expires_in em segundos. Em caso de 400 invalid_grant, consulte Solucionar problemas de uma troca com falha; a causa mais comum do lado do GitHub Actions é o formato da claim sub não corresponder (seu segmento final varia entre eventos ref:..., environment:... e pull_request).
Um subject_prefix de repo:your-org/* sozinho corresponde a todos os repositórios da sua organização e, sem uma restrição de ref, também corresponde a execuções de pull_request acionadas a partir de forks. Qualquer pessoa que possa abrir um pull request em um repositório correspondente poderia obter um token federado da Anthropic.
Restrinja o bloco match da regra ao escopo mais estreito que se adeque ao seu caso de uso:
subject_prefix: "repo:your-org/your-repo:*" para que outros repositórios da organização não correspondam."ref": "refs/heads/main" (ou sua branch de release) em claims para que execuções de pull request e branches de feature não correspondam."repository_owner": "your-org" em claims como uma verificação de defesa em profundidade contra casos extremos de parsing de sub.subject_prefix: "repo:your-org/your-repo:environment:production" e proteja esse ambiente com revisores obrigatórios no GitHub.Was this page helpful?