Claude Platform Docs
管理身分提供者

搭配 SPIFFE 使用 WIF

使用來自 SPIRE 或任何其他符合 SPIFFE 規範之簽發者的 JWT-SVID,向 Claude API 驗證 SPIFFE 工作負載的身分。

SPIFFE 是 CNCF 為工作負載簽發身分的標準。SPIRE 是其開源參考實作,此外也有數個商業產品會簽發符合 SPIFFE 規範的身分。Anthropic 可與任何能發出 OIDC 相容 JWT-SVID 的 SPIFFE 實作進行聯合。如需目前的實作清單,請參閱 SPIFFE 專案網站上的 Commercial software that implements SPIFFE

聯合可透過位於公開 HTTPS URL 的 OIDC 探索文件運作(discovery 模式,須遵守 URL 限制),或透過直接註冊 JWKS 運作(inline 模式)。

JWT-SVID 規格將 sub 定義為工作負載的 SPIFFE ID,而 SPIFFE Workload API 要求呼叫端在擷取時提供 aud,因此這些宣告(claims)在各實作之間是一致的。Anthropic 另外要求 issiat,這兩者皆非 JWT-SVID 規格所強制要求,因此請設定您的實作以填入這兩個宣告(在 SPIRE 中,issjwt_issuer 伺服器設定,而 iat 會自動設定)。具備這些條件後,本指南的設定 Anthropic取得並使用權杖以及限定規則範圍等章節適用於任何 SPIFFE 實作。

SPIFFE 會為每個工作負載指派一個格式為 spiffe://<trust-domain>/<path> 的穩定身分 URI,而 SPIRE 會透過 Workload API 依需求將該身分簽發為 JWT-SVID。JWT-SVID 是一個普通的已簽署 JWT,其 sub 宣告為工作負載的 SPIFFE ID,而其 aud 宣告則由工作負載在擷取時提供。

將 SPIRE 信任網域橋接至標準 OIDC 的元件是 SPIRE OIDC Discovery Provider,這是一個獨立的輔助程式,會為信任網域的 JWT 簽署金鑰發布 /.well-known/openid-configuration 與 JWKS 端點。在探索提供者執行的情況下,JWT-SVID 的驗證方式與任何其他 OIDC 權杖相同:將探索 URL 註冊為聯合簽發者(federation issuer),撰寫一條符合工作負載 SPIFFE ID 的聯合規則(federation rule),並讓工作負載將其 JWT-SVID 提交至 Anthropic 的權杖交換端點。

本頁的範例使用 SPIRE,並適用於任何執行 SPIRE Agent 的環境:Kubernetes pod、虛擬機器以及裸機主機。

先決條件

  • 熟悉 WIF 概念:服務帳戶、聯合簽發者與聯合規則。
  • 一個已簽發工作負載身分的 SPIFFE 部署(本頁範例使用 SPIRE Server 與 Agent),以及需要呼叫 Claude API 之工作負載的註冊項目。
  • 信任網域的 OIDC 探索端點(在 SPIRE 中為 OIDC Discovery Provider),以可公開存取的 HTTPS 端點執行,或已匯出 JWKS 以供 inline 註冊。
  • 您的 SPIFFE 簽發者已設定為將 JWT-SVID 上的 iss 宣告設為您將註冊為聯合簽發者 issuer_url 的值。對於 discovery 模式,這是探索端點的公開 URL(在 SPIRE 中為 jwt_issuer 伺服器設定)。
  • 您的工作負載可取得 JWT-SVID。WIF 僅接受 JWT-SVID,不接受 X.509-SVID。
  • 在 Claude Console 中為您的 Anthropic 組織建立服務帳戶、聯合簽發者與聯合規則的權限。

擷取 JWT-SVID 時要請求的 audience 值一律為 https://api.anthropic.com。請在 spiffe-helper 的 jwt_audience、Workload API 的 FetchJWTSVID 呼叫,以及聯合規則的 audience 比對器中使用此值。

設定 SPIRE

本節的說明為 SPIRE 專屬。如果您使用不同的 SPIFFE 簽發者,請依照其本身的文件設定其 OIDC 探索端點與 JWT-SVID 擷取方式,然後從設定 Anthropic 繼續。

如果您已經搭配 OIDC Discovery Provider 執行 SPIRE,與 Anthropic 聯合在 SPIRE 端需要三件事:一個與探索 URL 相符的 jwt_issuer、一個將呼叫 Claude API 之工作負載的註冊項目,以及讓該工作負載能以 Anthropic audience 擷取 JWT-SVID 的方式。以下各小節將逐一說明。設定片段僅顯示與 Anthropic 聯合相關的設定,而非完整的 SPIRE 部署設定。

驗證 JWT 簽發者

Anthropic 驗證 JWT-SVID 的方式,是將其 iss 宣告與已註冊的聯合簽發者比對,並從該簽發者的探索文件擷取 JWKS。兩項 SPIRE 設定必須使用相同的 URL:SPIRE Server 的 jwt_issuer(它會成為每個簽發之 JWT-SVID 中的 iss 宣告),以及 OIDC Discovery Provider 的 domains 清單(它決定探索文件與 JWKS 由哪個主機提供)。這個共用的 URL 就是您向 Anthropic 註冊的值。

信任網域與簽發者 URL 彼此獨立。信任網域(spiffe://prod.example.com)限定 sub 宣告的範圍。簽發者 URL(https://oidc-discovery.prod.example.com)是 Anthropic 擷取簽署金鑰的位置。兩者不需要共用主機名稱。

請確認 SPIRE Server 的設定中已設定 jwt_issuer,且指向探索提供者的公開 URL。以下範例也顯示了預設的 JWT-SVID 存留時間。SPIRE 的內建預設值為 5 分鐘,這短到必須持續輪替(請參閱執行 spiffe-helper)。Anthropic 的權杖交換端點會拒絕任何存留時間超過聯合簽發者所設定上限的身分權杖,該上限預設為 1 小時(請參閱驗證規則)。此檢查適用於每個 SPIFFE 實作,而不僅限於 SPIRE,因此請將 default_jwt_svid_ttl(或任何個別項目的覆寫值)保持在該上限以下或等於該上限。

server.conf
server {
    trust_domain         = "prod.example.com"
    jwt_issuer           = "https://oidc-discovery.prod.example.com"
    default_jwt_svid_ttl = "5m"
    # ...
}

在 OIDC Discovery Provider 的設定中,相同的主機名稱必須出現在 domains 之下,且該提供者必須能夠連線至 SPIRE Server 的 API socket。該提供者透過 HTTPS 提供探索文件與 JWKS。請使用其內建的 ACME 支援終止 TLS,或在其前方放置能終止 TLS 的負載平衡器。

oidc-discovery-provider.conf
domains = ["oidc-discovery.prod.example.com"]

server_api {
    address = "unix:///run/spire/sockets/private/api.sock"
}

acme {
    email        = "platform@example.com"
    tos_accepted = true
}

註冊工作負載

每個呼叫 Claude API 的工作負載都需要一個 SPIRE 註冊項目,將其執行階段選擇器(selectors)對應至 SPIFFE ID。如果工作負載已經註冊,請記下其 SPIFFE ID,您會在聯合規則的 subject_prefix 中使用它。如果尚未註冊,請進行註冊。對於 Kubernetes pod,選擇器通常是命名空間與 Kubernetes 服務帳戶:

CLI
# 將 NODE_UID 替換為節點的 UID:
#   kubectl get node <node-name> -o jsonpath='{.metadata.uid}'
spire-server entry create \
    -spiffeID spiffe://prod.example.com/ns/inference/sa/worker \
    -parentID spiffe://prod.example.com/spire/agent/k8s_psat/prod-cluster/NODE_UID \
    -selector k8s:ns:inference \
    -selector k8s:sa:worker

Kubernetes 以外的工作負載使用主機層級的選擇器,例如 unix:uid:1000unix:path 也可使用,但需要在 agent 的 unix workload attestor 設定中設定 discover_workload_path = true)。執行 spire-controller-manager 的叢集可以使用 ClusterSPIFFEID 自訂資源宣告項目,而不必直接呼叫 spire-server entry create

執行 spiffe-helper

spiffe-helper 是一個 sidecar 公用程式,它會連線至 SPIRE Agent socket、為指定的 audience 擷取 JWT-SVID、將其寫入檔案,並在到期前重新擷取。該輔助程式預設以 daemon 模式執行。以下範例明確設定 daemon_mode = true

helper.conf
agent_address = "/run/spire/sockets/agent.sock"
# The JWT-SVID file is written under cert_dir
cert_dir      = "/var/run/secrets/anthropic.com"
daemon_mode   = true

jwt_svids = [{
    jwt_audience       = "https://api.anthropic.com"
    jwt_svid_file_name = "token"
}]

在 Kubernetes 中,請將 spiffe-helper 作為 sidecar 容器執行,並與您的應用程式容器共用一個以記憶體為後端的 emptyDir 磁碟區(medium: Memory),使 bearer SVID 永遠不會落在節點的磁碟上。將 SPIRE Agent socket 從主機掛載至 sidecar,在兩個容器中將共用磁碟區掛載於 /var/run/secrets/anthropic.com,並在應用程式容器上設定 ANTHROPIC_IDENTITY_TOKEN_FILE=/var/run/secrets/anthropic.com/token。在 VM 與裸機上,請將 spiffe-helper 作為系統服務與工作負載一同執行,並讓兩者指向共用目錄。

設定 Anthropic

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

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

**聯合簽發者:**以 discovery 模式註冊 OIDC Discovery Provider 的公開 URL。Anthropic 會從此 URL 擷取 /.well-known/openid-configuration,並依循回傳的 jwks_uri 取得信任網域的簽署金鑰。

{
  "name": "spire-prod",
  "issuer_url": "https://oidc-discovery.prod.example.com",
  "jwks": { "type": "discovery" }
}

如果探索提供者無法從公開網際網路存取,請自行擷取 JWKS(curl https://oidc-discovery.prod.example.com/keys),並使用回傳之 keys 陣列的內容,以 "jwks": {"type": "inline", "keys": [...]} 註冊簽發者。在 inline 模式下,issuer_url 僅會與 JWT-SVID 的 iss 宣告進行比對。Anthropic 永遠不會嘗試連線至該 URL。

若要在不公開探索端點的情況下自動更新 JWKS,請設定 SPIRE Server 的 BundlePublisher 外掛程式(aws_s3gcp_cloudstoragek8s_configmap)並設定 format = "jwks",以便在每次輪替時將 JWT 簽署金鑰推送至外部儲存空間,然後透過 Admin API 更新簽發者的 inline 金鑰。

**聯合規則:**比對 JWT-SVID 的 sub(SPIFFE ID)以及您設定 spiffe-helper 請求的 aud。SPIFFE ID 是 URI 字串,而 subject_prefix 將其視為不透明文字進行比對,因此精確值或結尾為 * 的前綴比對皆可適用。對於更複雜的模式,請使用 CEL condition

{
  "name": "spire-inference-worker",
  "issuer_id": "fdis_...",
  "match": {
    "subject_prefix": "spiffe://prod.example.com/ns/inference/sa/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
}

token_lifetime_seconds 是交換所回傳之 Anthropic 存取權杖的存留時間,而非 JWT-SVID 的存留時間。SDK 會自動重新整理存取權杖。

請盡可能依工作負載所允許的程度具體設定。僅當註冊於該路徑下的每個工作負載都應對應至同一個 Anthropic 服務帳戶時,才將 subject_prefix 放寬為 spiffe://prod.example.com/ns/inference/*。將規則的 fdrl_... ID 新增至工作負載的 ANTHROPIC_FEDERATION_RULE_ID 環境變數。

取得並使用權杖

Anthropic SDK 可以從 spiffe-helper 維護的檔案讀取 JWT-SVID,或透過權杖提供者 callable 直接呼叫 SPIFFE Workload API。檔案路徑是最簡單的整合方式,且適用於每種 SDK 語言。callable 路徑可省去 sidecar,但需要您應用程式語言的 SPIFFE Workload API 用戶端。

在 spiffe-helper 將新的 JWT-SVID 寫入 /var/run/secrets/anthropic.com/token 的情況下,將 ANTHROPIC_IDENTITY_TOKEN_FILE 設為該路徑,並同時設定 ANTHROPIC_FEDERATION_RULE_IDANTHROPIC_ORGANIZATION_IDANTHROPIC_SERVICE_ACCOUNT_IDANTHROPIC_WORKSPACE_ID。SDK 會在每次權杖交換時讀取該檔案,因此它總是會取得最近輪替的 SVID,並在 Anthropic 存取權杖到期前自動重新整理。請參閱環境變數以了解每個值的來源。

import anthropic

# 讀取 spiffe-helper 寫入至
# ANTHROPIC_IDENTITY_TOKEN_FILE 的 JWT-SVID,以及 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"))

驗證設定

在接入 SDK 之前,請直接從 SPIRE Agent 擷取 JWT-SVID,並確認其宣告符合您的聯合規則所預期的內容。如果您使用不同的 SPIFFE 實作,請使用其 CLI 或 Workload API 用戶端擷取 JWT-SVID,並以相同方式解碼 payload。

CLI
spire-agent api fetch jwt \
    -audience https://api.anthropic.com \
    -socketPath /run/spire/sockets/agent.sock \
    -output json \
  | jq -r '.[0].svids[0].svid' \
  | jq -rR 'split(".")[1] | gsub("-";"+") | gsub("_";"/") | @base64d | fromjson'

-output json 旗標會將 SVID 回應與 bundle 回應以兩個元素的 JSON 陣列回傳,因此 jq -r '.[0].svids[0].svid' 可擷取出純權杖。在沒有 -output 的較舊 SPIRE 版本上,該命令會改為印出帶標籤的區塊。在這種情況下,請將預設輸出透過管線傳給 awk '/^[[:space:]]*eyJ/{print $1; exit}' 以擷取權杖行。請檢查 iss 是否為您註冊的 OIDC Discovery Provider URL、sub 是否為工作負載的 SPIFFE ID,以及 aud 是否包含 https://api.anthropic.com。然後執行取得並使用權杖中的 cURL 範例。成功的交換會回傳以 sk-ant-oat01- 開頭的 access_token。如果交換失敗並回傳不透明的 401 authentication_error 回應(訊息為 Authentication failed),請查看驗證歷史記錄頁面以了解拒絕原因,並參閱疑難排解失敗的交換。SPIRE 端最常見的原因是 SPIRE Server 的 jwt_issuer 與註冊為聯合簽發者的 URL 不一致。

限定規則範圍

SPIFFE ID 路徑慣例由操作者定義,因此聯合規則的 subject_prefix 比對器應反映您的註冊項目所使用的路徑結構。常見的結構包括 spiffe://<trust-domain>/ns/<namespace>/sa/<service-account>(spire-controller-manager 中 ClusterSPIFFEID 資源發出的預設值),以及用於 VM 與裸機工作負載的 spiffe://<trust-domain>/host/<hostname>/<service>

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

  • **固定至單一工作負載:**將 subject_prefix 設為完整的 SPIFFE ID,結尾不加 *
  • **一律設定 audience:**在規則上要求 audience,並以相同的值設定 spiffe-helper(或 Workload API 呼叫),使為其他依賴方簽發的 SVID 遭到拒絕。
  • **依路徑區段限定範圍:**使用 spiffe://prod.example.com/ns/inference/* 授權註冊於某命名空間下的每個工作負載,並為每個命名空間建立個別的規則與 Anthropic 服務帳戶,而非放寬單一規則。
  • **每個信任網域一個簽發者:**每個 SPIRE 信任網域都有自己的簽署金鑰與 OIDC Discovery Provider。請將每個信任網域註冊為個別的聯合簽發者,並將規則繫結至擁有其所比對之 SPIFFE ID 的簽發者。

後續步驟

使用 Workload Identity Federation 將 Okta 服務應用程式身分聯合至 Claude API。

使用來自您自己身分提供者的短期身分權杖向 Claude API 驗證工作負載,而非使用長期靜態 API 金鑰。

Workload Identity Federation 的環境變數、驗證規則、設定檔設定與錯誤參考。

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

Was this page helpful?