Claude Platform Docs
管理身分提供者

搭配 Kubernetes 使用 WIF

使用投射的服務帳戶權杖,從自行管理的 Kubernetes 叢集向 Claude API 進行身分驗證。

自行管理的 Kubernetes 叢集(kubeadm、k3s、OpenShift 以及地端部署的發行版)會透過 projected service account tokens(投射的服務帳戶權杖)為每個 pod 簽署 OIDC「JSON Web Token」(JSON 網路權杖),即 JWT。叢集的 API 伺服器充當 OIDC 簽發者(issuer),而每個權杖的 sub 宣告遵循 system:serviceaccount:<namespace>:<service-account> 的格式。您可以透過讀取叢集的探索文件(discovery document)來找到叢集的簽發者 URL:

cURL
kubectl get --raw /.well-known/openid-configuration | jq -r .issuer

先決條件

  • 熟悉 WIF 概念:服務帳戶、聯合簽發者(federation issuers)與聯合規則(federation rules)。
  • 一個在 API 伺服器上已設定 --service-account-issuer 旗標的 Kubernetes 叢集。大多數發行版預設會設定此值;kubeadm 叢集通常使用 https://kubernetes.default.svc.cluster.local。如果您無法直接存取 API 伺服器設定,您的平台團隊可以確認該值。
  • 下列其中一項,以便 Anthropic 能夠驗證權杖簽章:
    • 簽發者的 JWKS 端點可從公開網際網路透過 HTTPS 在連接埠 443 上存取,或
    • 您可以從叢集內部擷取 JWKS,並以 inline 模式註冊(詳見設定 Anthropic)。
  • 在 Claude Console 中為您的 Anthropic 組織建立服務帳戶、聯合簽發者與聯合規則的權限。

設定 Kubernetes

將服務帳戶權杖投射到您的 pod 中,並使用您的聯合規則所預期的受眾(audience)與存留時間。serviceAccountToken 投射會將一個新的 JWT 寫入掛載路徑,並在 expirationSeconds 到期之前輪替它。

Pod
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

為此 pod 簽發的權杖帶有 sub: "system:serviceaccount:inference:inference-worker"aud: ["https://api.anthropic.com"]

設定 Anthropic

在 Claude Console 中,開啟 Settings → Workload identity,點擊 Connect workload,然後選取 Kubernetes 圖塊。精靈會引導您完成註冊簽發者、建立服務帳戶以及建立聯合規則。

精靈會為您建立這些資源。無論您是在精靈中輸入這些值,還是將它們傳送至 Admin API,請使用下列值:

聯合簽發者: 許多自行管理的叢集使用諸如 https://kubernetes.default.svc.cluster.local 之類無法從公開網際網路存取的簽發者 URL。如果您的叢集屬於這種情況,請選擇 inline JWKS 來源並貼上叢集的金鑰。從叢集內部擷取它們:

cURL
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 僅用於與 JWT 的 iss 宣告進行比對;Anthropic 絕不會嘗試連線至該 URL。如果您的簽發者可公開存取,請改用 "jwks": {"type": "discovery"}

聯合規則: 比對服務帳戶的 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
}

請在工作負載允許的範圍內盡可能具體。僅當命名空間中的每個服務帳戶都應對應到同一個 Anthropic 服務帳戶時,才將 subject_prefix 放寬為 system:serviceaccount:inference:*(結尾的 * 使其成為前綴比對)。將規則的 fdrl_... ID 加入您 pod 的 ANTHROPIC_FEDERATION_RULE_ID 環境變數中。

取得並使用權杖

設定 Kubernetes 中的 pod 規格將 ANTHROPIC_IDENTITY_TOKEN_FILE 設定為投射的掛載路徑,並同時設定 ANTHROPIC_FEDERATION_RULE_IDANTHROPIC_ORGANIZATION_IDANTHROPIC_SERVICE_ACCOUNT_IDANTHROPIC_WORKSPACE_ID。這些設定就緒後,SDK 會在每次交換時從磁碟讀取權杖,並自動重新整理 Anthropic 存取權杖。

import anthropic

# 從 pod 的環境中讀取 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"))

驗證設定

成功的交換會回傳一個以 sk-ant-oat01- 開頭的 access_token,以及一個以秒為單位的 expires_in 值。如果交換失敗並回傳不透明的 401 authentication_error 回應(訊息為 Authentication failed),請查看身分驗證歷史記錄頁面以了解拒絕原因,並參閱疑難排解失敗的交換;Kubernetes 端最常見的原因是 JWKS 金鑰不符(對於 inline 模式,請使用 kubectl get --raw /openid/v1/jwks 重新擷取並更新簽發者)。

限定規則範圍

將規則的 match 區塊鎖定在符合您使用情境的最小範圍:

  • 固定命名空間與服務帳戶名稱: 使用完整的 system:serviceaccount:<namespace>:<name> 值,結尾不加 *
  • 務必設定受眾: 在規則上要求 audience,並在 pod 的 serviceAccountToken 投射上設定相同的值,以便拒絕預設受眾權杖。
  • 每個命名空間使用獨立的規則: 為每個命名空間建立各自的規則與 Anthropic 服務帳戶,而非放寬單一規則。
  • 將 inline-JWKS 簽發者限定於單一叢集: 當多個叢集共用一個簽發者 URL 時,請將每個叢集的 JWKS 註冊為各自的聯合簽發者,並僅將規則繫結至該簽發者。

後續步驟

Was this page helpful?