Использование WIF с Kubernetes
Аутентификация в Claude API из самостоятельно управляемых кластеров Kubernetes с помощью проецируемых токенов сервисных аккаунтов.
Самостоятельно управляемые кластеры Kubernetes (kubeadm, k3s, OpenShift и локальные дистрибутивы) подписывают OIDC JSON Web Tokens (JWT) для каждого пода через проецируемые токены сервисных аккаунтов (projected service account tokens). API-сервер кластера выступает в роли издателя OIDC (OIDC issuer), а claim sub каждого токена имеет вид system:serviceaccount:<namespace>:<service-account>. Вы можете узнать URL издателя вашего кластера, прочитав его discovery-документ:
kubectl get --raw /.well-known/openid-configuration | jq -r .issuerПредварительные требования
- Знакомство с концепциями WIF: сервисные аккаунты, издатели федерации и правила федерации.
- Кластер Kubernetes с настроенным на API-сервере флагом
--service-account-issuer. Большинство дистрибутивов устанавливают его по умолчанию; кластеры kubeadm обычно используютhttps://kubernetes.default.svc.cluster.local. Ваша платформенная команда может подтвердить это значение, если у вас нет прямого доступа к конфигурации API-сервера. - Одно из следующих условий, чтобы Anthropic мог проверять подписи токенов:
- Конечная точка JWKS издателя доступна из публичного интернета по HTTPS на порту 443, или
- Вы можете получить JWKS изнутри кластера и зарегистрировать его в режиме
inline(описано в разделе Настройка Anthropic).
- Разрешение на создание сервисных аккаунтов, издателей федерации и правил федерации в Claude Console для вашей организации Anthropic.
Настройка Kubernetes
Спроецируйте токен сервисного аккаунта в ваш под с аудиторией (audience) и временем жизни, которые ожидает ваше правило федерации. Проекция serviceAccountToken записывает свежий JWT по пути монтирования и обновляет его до истечения expirationSeconds.
apiVersion: v1
kind: Pod
metadata:
name: inference-worker
namespace: inference
spec:
serviceAccountName: inference-worker
volumes:
- name: anthropic-token
projected:
sources:
- serviceAccountToken:
audience: https://api.anthropic.com
expirationSeconds: 3600
path: token
containers:
- name: app
image: your-registry/inference-worker:latest
env:
- name: ANTHROPIC_IDENTITY_TOKEN_FILE
value: /var/run/secrets/anthropic.com/token
- name: ANTHROPIC_FEDERATION_RULE_ID
value: fdrl_...
- name: ANTHROPIC_ORGANIZATION_ID
value: 00000000-0000-0000-0000-000000000000
- name: ANTHROPIC_SERVICE_ACCOUNT_ID
value: svac_...
- name: ANTHROPIC_WORKSPACE_ID # required when the rule covers multiple workspaces
value: wrkspc_...
volumeMounts:
- name: anthropic-token
mountPath: /var/run/secrets/anthropic.com
readOnly: trueТокен, выданный для этого пода, содержит sub: "system:serviceaccount:inference:inference-worker" и aud: ["https://api.anthropic.com"].
Настройка Anthropic
В Claude Console откройте Settings → Workload identity, нажмите Connect workload и выберите плитку Kubernetes. Мастер проведёт вас через регистрацию издателя, создание сервисного аккаунта и создание правила федерации.
Мастер создаёт эти ресурсы за вас. Используйте следующие значения независимо от того, вводите ли вы их в мастере или отправляете в Admin API:
Издатель федерации: Многие самостоятельно управляемые кластеры используют URL издателя, например https://kubernetes.default.svc.cluster.local, который недоступен из публичного интернета. Если это относится к вашему кластеру, выберите источник JWKS inline и вставьте ключи кластера. Получите их изнутри кластера:
kubectl get --raw /openid/v1/jwksЗатем настройте издателя, используя содержимое возвращённого массива keys (а не окружающую обёртку {"keys": [...]}):
{
"name": "onprem-k8s",
"issuer_url": "https://kubernetes.default.svc.cluster.local",
"jwks": {
"type": "inline",
"keys": [{ "kty": "RSA", "kid": "...", "n": "...", "e": "AQAB" }]
}
}В режиме inline значение issuer_url только сравнивается с claim iss в JWT; Anthropic никогда не пытается к нему обратиться. Если ваш издатель публично доступен, используйте вместо этого "jwks": {"type": "discovery"}.
Правило федерации: Сопоставьте claim sub сервисного аккаунта и аудиторию, которую вы задали для проецируемого токена.
{
"name": "onprem-inference",
"issuer_id": "fdis_...",
"match": {
"subject_prefix": "system:serviceaccount:inference:inference-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
}Будьте настолько конкретны, насколько позволяет рабочая нагрузка. Ослабляйте subject_prefix до system:serviceaccount:inference:* (завершающий * превращает его в сопоставление по префиксу) только в том случае, если каждый сервисный аккаунт в пространстве имён должен отображаться на один и тот же сервисный аккаунт Anthropic. Добавьте идентификатор правила fdrl_... в переменную окружения ANTHROPIC_FEDERATION_RULE_ID вашего пода.
Получение и использование токена
Спецификация пода в разделе Настройка Kubernetes устанавливает ANTHROPIC_IDENTITY_TOKEN_FILE в путь проецируемого монтирования, а также ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID и ANTHROPIC_WORKSPACE_ID. Когда они заданы, SDK считывает токен с диска при каждом обмене и автоматически обновляет токен доступа Anthropic.
import anthropic
# Читает ANTHROPIC_IDENTITY_TOKEN_FILE, ANTHROPIC_FEDERATION_RULE_ID,
# ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID и ANTHROPIC_WORKSPACE_ID
# из окружения пода.
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"))Проверка настройки
Успешный обмен возвращает access_token, начинающийся с sk-ant-oat01-, и значение expires_in в секундах. Если обмен завершается непрозрачным ответом 401 authentication_error (сообщение Authentication failed), проверьте страницу истории аутентификации, чтобы узнать причину отказа, и см. раздел Устранение неполадок при неудачном обмене; наиболее распространённая причина на стороне Kubernetes — несоответствие ключей JWKS (для режима inline повторно получите их с помощью kubectl get --raw /openid/v1/jwks и обновите издателя).
Ограничение области действия правила
Ограничьте блок match правила самой узкой областью, подходящей для вашего сценария использования:
- Зафиксируйте пространство имён и имя сервисного аккаунта: Используйте полное значение
system:serviceaccount:<namespace>:<name>без завершающего*. - Всегда задавайте аудиторию: Требуйте
audienceв правиле и задайте то же значение в проекцииserviceAccountTokenпода, чтобы токены с аудиторией по умолчанию отклонялись. - Используйте отдельное правило для каждого пространства имён: Создавайте отдельное правило и сервисный аккаунт Anthropic для каждого пространства имён вместо расширения одного правила.
- Ограничивайте издателей с inline-JWKS одним кластером: Когда несколько кластеров используют один URL издателя, зарегистрируйте JWKS каждого кластера как отдельного издателя федерации и привязывайте правила только к этому издателю.
Следующие шаги
- Workload Identity Federation: концепции, процесс обмена токенов и параметры конфигурации SDK.
- Справочник по WIF: переменные окружения, режимы источников JWKS и режимы сопоставления правил.
Was this page helpful?