Каждый запуск рабочего процесса GitHub Actions может запросить подписанный токен идентификации у размещённого эмитента GitHub по адресу https://token.actions.githubusercontent.com. С помощью «Workload Identity Federation» (федерации идентификации рабочих нагрузок) ваш рабочий процесс обменивает этот токен на короткоживущий токен доступа Anthropic, так что ваши задания CI могут вызывать Claude API без секрета ANTHROPIC_API_KEY, хранящегося в вашем репозитории.
Утверждение sub токена кодирует репозиторий и контекст триггера. Для push в ветку оно имеет вид repo:<owner>/<repo>:ref:refs/heads/<branch>. Запуски по pull request используют repo:<owner>/<repo>:pull_request, а развёртывания, ограниченные окружением, используют repo:<owner>/<repo>:environment:<name>. Ваше правило федерации сопоставляется с этим утверждением (и другими, такими как repository_owner и ref), чтобы решить, каким запускам рабочего процесса разрешено проходить аутентификацию.
id-token: write.GitHub выдаёт токен идентификации только тем заданиям, которые явно его запрашивают. Добавьте разрешение id-token: write на уровне рабочего процесса или задания:
permissions:
id-token: write
contents: readВнутри задания раннер предоставляет две переменные окружения: ACTIONS_ID_TOKEN_REQUEST_URL и ACTIONS_ID_TOKEN_REQUEST_TOKEN. Вызовите URL запроса, передав токен запроса в качестве bearer-учётных данных и выбранную вами аудиторию в качестве параметра запроса, затем запишите возвращённый «JSON Web Token» (веб-токен JSON), или JWT, в файл:
- 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-jwtЕсли вы предпочитаете JavaScript, actions/github-script предоставляет ту же возможность через 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);Декодированный токен содержит утверждения, описывающие запуск рабочего процесса. Ваше правило федерации сопоставляется с ними:
{
"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"
}Полный список форматов sub см. в справочнике GitHub по утверждениям субъекта OIDC.
Следуйте пошаговому руководству по настройке, чтобы зарегистрировать эмитент федерации, создать сервисный аккаунт Anthropic и создать правило федерации в Claude Console. Используйте следующие значения, специфичные для GitHub Actions.
Эмитент федерации: GitHub публикует свой документ обнаружения OIDC и JWKS в открытом доступе, поэтому используйте режим обнаружения. Anthropic автоматически обновляет ключи, когда GitHub их ротирует.
{
"name": "github-actions",
"issuer_url": "https://token.actions.githubusercontent.com",
"jwks_source": "discovery"
}Правило федерации: Сопоставляйте только те запуски рабочих процессов, которым вы намерены доверять. См. раздел Ограничение рабочих процессов, которые могут проходить аутентификацию, чтобы узнать, как безопасно ограничить область этих утверждений.
{
"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
}Будьте настолько конкретны, насколько позволяет рабочая нагрузка. Ослабляйте subject_prefix до repo:your-org/your-repo:* (в паре с ограничением claims.ref) только в том случае, если правило должно соответствовать нескольким типам событий из одного репозитория, поскольку завершающий сегмент sub различается между событиями ref:..., environment:... и pull_request.
Установите переменные окружения федерации для задания и вызывайте SDK обычным образом. Anthropic() считывает ANTHROPIC_IDENTITY_TOKEN_FILE, обменивает JWT при первом запросе и автоматически обновляет токен доступа до истечения срока его действия.
import anthropic
# Считывает ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID,
# ANTHROPIC_SERVICE_ACCOUNT_ID, ANTHROPIC_WORKSPACE_ID и ANTHROPIC_IDENTITY_TOKEN_FILE
# из окружения задания.
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)Каждый токен идентификации, выданный GitHub, истекает примерно через пять минут после выдачи. Конечная точка запроса токена (ACTIONS_ID_TOKEN_REQUEST_URL) остаётся действительной на протяжении всего задания, поэтому вы можете получить свежий токен в любой момент. SDK обменивает токен при первом использовании и кэширует полученный токен доступа Anthropic. Для заданий, которые выполняются дольше, чем срок действия токена Anthropic, SDK повторно считывает ANTHROPIC_IDENTITY_TOKEN_FILE при каждом обновлении, поэтому периодически повторно запускайте шаг получения токена (или оберните его в фоновый цикл), чтобы поддерживать файл в актуальном состоянии. В качестве альтернативы передайте в SDK обратный вызов поставщика токенов, который напрямую обращается к ACTIONS_ID_TOKEN_REQUEST_URL вместо использования пути к файлу.
Успешный обмен возвращает access_token, начинающийся с sk-ant-oat01-, и значение expires_in в секундах. При ошибке 400 invalid_grant см. раздел Устранение неполадок при неудачном обмене; наиболее частая причина со стороны GitHub Actions — несоответствие формата утверждения sub (его завершающий сегмент различается между событиями ref:..., environment:... и pull_request).
Значение subject_prefix, равное repo:your-org/*, само по себе соответствует каждому репозиторию в вашей организации, а без ограничения ref оно также соответствует запускам pull_request, инициированным из форков. Любой, кто может открыть pull request к соответствующему репозиторию, сможет получить федеративный токен Anthropic.
Ограничьте блок match правила до наиболее узкой области, подходящей для вашего сценария использования:
subject_prefix: "repo:your-org/your-repo:*", чтобы другие репозитории в организации не соответствовали правилу."ref": "refs/heads/main" (или вашу релизную ветку) в claims, чтобы запуски по pull request и feature-ветки не соответствовали правилу."repository_owner": "your-org" в claims в качестве дополнительной защиты от пограничных случаев при разборе sub.subject_prefix: "repo:your-org/your-repo:environment:production" и защитите это окружение обязательными рецензентами в GitHub.Was this page helpful?