WIF reference
WIF reference
이 페이지는 Workload Identity Federation의 구성 표면, 검증 제약, 오류 매핑을 모아 둔 문서예요. 설정 워크스루는 공급자 가이드를 참고하세요.
출처: 문서
본문
토큰 교환 요청
POST /v1/oauth/token은 RFC 7523 jwt-bearer 부여를 사용하는 JSON 본문을 받아요. SDK는 환경 변수에서 이 요청을 만들어 줘요. 각 공급자 가이드의 cURL 예시가 원시 본문을 보여줘요.
| 필드 | 필수 | 설명 |
|---|---|---|
grant_type |
예 | 항상 urn:ietf:params:oauth:grant-type:jwt-bearer. |
assertion |
예 | 내 아이덴티티 공급자가 발행한 OIDC JWT. |
federation_rule_id |
예 | 평가할 페더레이션 규칙의 태그 ID(fdrl_...). |
organization_id |
예 | 내 Anthropic 조직의 UUID. |
service_account_id |
예 | 대상 서비스 계정의 태그 ID(svac_...). |
workspace_id |
조건부 | 발행되는 토큰을 범위 지을 워크스페이스의 태그 ID(wrkspc_...), 또는 조직 기본 워크스페이스의 리터럴 default. 규칙이 둘 이상의 워크스페이스에 활성화된 경우 필수. 생략하면 서버는 규칙의 유일한 활성 워크스페이스를 선택한다. |
토큰 교환 응답
POST /v1/oauth/token은 표준 OAuth 2.0 토큰 응답(RFC 6749 §5.1)을 반환해요:
| 필드 | 타입 | 설명 |
|---|---|---|
access_token |
string | sk-로 시작하는 수명이 짧은 Anthropic 토큰. Authorization: Bearer ...로 전달하세요. |
token_type |
string | 항상 Bearer. |
expires_in |
integer | 토큰이 만료되기까지의 초. |
scope |
string | 일치한 규칙이 부여한 OAuth 범위. |
환경 변수
SDK는 생성자 인자 없이 페더레이션 토큰 교환을 수행하기 위해 다음 변수들을 읽어요.
| 변수 | 필수 | 설명 | 예시 |
|---|---|---|---|
ANTHROPIC_FEDERATION_RULE_ID |
예 | 평가할 페더레이션 규칙의 태그 ID. | fdrl_... |
ANTHROPIC_ORGANIZATION_ID |
예 | 내 Anthropic 조직의 UUID. Claude Console의 Settings > Organization에서 찾을 수 있어요. | 00000000-0000-0000-0000-000000000000 |
ANTHROPIC_IDENTITY_TOKEN_FILE |
_TOKEN_FILE 또는 _TOKEN 중 하나 |
내 아이덴티티 공급자(IdP)가 발행한 JWT의 파일 경로. SDK는 매 교환마다 이 파일을 다시 읽어 디스크에서 회전하는 프로젝티드 토큰이 항상 최신이 되게 해요. | /var/run/secrets/anthropic.com/token |
ANTHROPIC_IDENTITY_TOKEN |
_TOKEN_FILE 또는 _TOKEN 중 하나 |
리터럴 JWT 문자열. 플랫폼이 토큰을 파일이 아니라 환경 변수로 주입할 때 사용하세요. | eyJhbG...NiIs... |
ANTHROPIC_SERVICE_ACCOUNT_ID |
예 | 발행된 접근 토큰이 행동하는 대상 Anthropic 서비스 계정의 태그 ID. | svac_... |
ANTHROPIC_WORKSPACE_ID |
조건부 | 발행되는 토큰을 범위 지을 워크스페이스의 태그 ID 또는 리터럴 default. 페더레이션 규칙이 둘 이상의 워크스페이스에 활성화된 경우 필수. 단일 워크스페이스에 바인딩된 규칙에서는 선택. 발행되는 토큰은 교환 시 이 워크스페이스에 범위가 제한되므로 워크스페이스를 바꾸려면 새 교환이 필요해요. |
wrkspc_... |
ANTHROPIC_PROFILE |
아니요 | 로드할 구성 프로필 이름. 이 표의 페더레이션 환경 변수보다 우선해요. | staging-profile |
직접 환경 변수 페더레이션 경로는 ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID, 그리고 ANTHROPIC_IDENTITY_TOKEN_FILE 또는 ANTHROPIC_IDENTITY_TOKEN 중 하나가 모두 설정된 경우에만 활성화돼요. ANTHROPIC_WORKSPACE_ID는 곁에서 읽히지만 활성화를 게이트하지는 않아요.
경고 빈 문자열로 설정된 변수는 여전히 자격 증명 우선순위 체인에서 자리 하나를 차지해요.
ANTHROPIC_API_KEY=""가 내보내지면 SDK는 페더레이션으로 넘어가는 대신 빈 키로 API 키 경로를 선택해요. 사용하지 않는 자격 증명 변수는 비우지 말고 해제하세요.
자격 증명 우선순위
SDK는 이 순서로 자격 증명을 해결해요. 자격 증명을 산출하는 첫 소스가 이겨요.
| 순서 | 소스 | 참고 |
|---|---|---|
| 1 | 생성자 인자(api_key=, auth_token=, credentials=) |
항상 다른 모든 것을 재정의한다. |
| 2 | ANTHROPIC_API_KEY 또는 ANTHROPIC_AUTH_TOKEN |
페더레이션 전체를 그림자 처럼 가린다. API 키에서 마이그레이션할 때 이들을 해제하세요. |
| 3 | ANTHROPIC_PROFILE |
<config_dir>/configs/<name>.json을 로드한다. 명명된 프로필이 없으면 넘어가는 게 아니라 오류다. |
| 4 | 페더레이션 환경 변수 | ANTHROPIC_FEDERATION_RULE_ID + ANTHROPIC_ORGANIZATION_ID + ANTHROPIC_SERVICE_ACCOUNT_ID + ANTHROPIC_IDENTITY_TOKEN[_FILE]. |
| 5 | 활성 프로필 | <config_dir>/active_config에서 해결되며, default라는 프로필로 대체된다. |
프로필이 로드되면 환경 변수는 프로필이 생략한 필드를 채우지만 프로필이 명시적으로 설정한 필드는 절대 재정의하지 않아요. 예를 들어 ANTHROPIC_WORKSPACE_ID는 활성 프로필이 workspace_id를 설정하지 않을 때만 그것을 채워요.
프로필 구성 파일
프로필은 SDK와 ant CLI 둘 다 읽는 명명된 구성 파일이에요. 프로필을 사용하면 페더레이션 파라미터를 컨테이너 이미지와 함께 배포하거나 코드 변경 없이 환경 사이를 전환할 수 있어요.
구성 디렉터리
SDK는 이 순서로 구성 디렉터리를 찾아요:
$ANTHROPIC_CONFIG_DIR- Linux와 macOS에서
~/.config/anthropic - Windows에서
%APPDATA%\Anthropic
활성 프로필
활성 프로필 이름은 이 순서로 해결돼요:
$ANTHROPIC_PROFILE<config_dir>/active_config의 내용(ant profile activate <name>이 쓰는 한 줄 파일)- 리터럴 이름
default
Claude Code와 Claude Agent SDK는 이 같은 해결 순서를 존중하므로, 여기 구성한 페더레이션 프로필은 추가 설정 없이 그 도구들도 인증해요.
파일 레이아웃
| 경로 | 내용 | 민감도 |
|---|---|---|
<config_dir>/configs/<profile>.json |
version, authentication 블록, organization_id, workspace_id, base_url. |
기밀 아님. 커밋하거나 이미지에 구워도 안전하다. |
<config_dir>/credentials/<profile>.json |
version, 캐시된 access_token, expires_at, (대화형 로그인의 경우) refresh_token. |
기밀. SDK가 모드 0600으로 쓴다. |
구성 파일과 자격 증명 파일 둘 다 major.minor 형식(현재 "1.0")의 최상위 문자열 version 필드를 나른다. SDK는 미래 릴리스가 이전 형식을 감지·마이그레이션할 수 있도록 이 필드를 자동으로 써요. 손으로 구성할 때는 생략해도 되고 SDK는 파일을 현재 버전으로 취급해요.
페더레이션 프로필 예시
{
"version": "1.0",
"authentication": {
"type": "oidc_federation",
"federation_rule_id": "fdrl_...",
"service_account_id": "svac_...",
"identity_token": {
"source": "file",
"path": "/var/run/secrets/anthropic.com/token"
}
},
"organization_id": "00000000-0000-0000-0000-000000000000",
"workspace_id": "wrkspc_...",
"base_url": "https://api.anthropic.com"
}
authentication.identity_token을 생략하면 SDK는 환경의 ANTHROPIC_IDENTITY_TOKEN_FILE 또는 ANTHROPIC_IDENTITY_TOKEN으로 대체해요.
OAuth 범위
페더레이션 규칙에 설정하는 oauth_scope는 발행되는 접근 토큰이 호출할 수 있는 Claude API 엔드포인트를 결정해요.
| 범위 | 접근 권한 |
|---|---|
workspace:developer |
규칙의 워크스페이스에서 모든 비관리 Claude API 엔드포인트: Messages(스트리밍·토큰 계산 포함), Models, Managed Agents와 그 세션, Files, Skills. 같은 워크스페이스의 워크스페이스 API 키가 가진 접근과 일치한다. |
workspace:inference |
규칙의 워크스페이스에서 추론 엔드포인트: Messages(스트리밍·토큰 계산 포함), Models, OpenAI 호환 채팅 엔드포인트. Claude를 호출하기만 하고 Files, Skills, 다른 리소스는 관리할 필요가 없는 워크로드에 사용하세요. |
workspace:manage_tunnels |
MCP 터널 API: 터널 생성·나열·조회, CA 인증서 등록·보관, 터널 토큰 노출·회전, 터널 보관. Console의 터널 생성 모달 창은 규칙을 만들 때 이 범위를 잠근다. |
org:admin |
Admin API(조직 구성원, 초대, 워크스페이스, API 키, 그리고 나머지) 전체 접근. OAuth org:admin 토큰은 workspace:developer 또는 workspace:inference로 범위 제한된 규칙만 만들거나 수정할 수 있고, 다른 범위의 규칙의 기반이 되는 발급자는 업데이트할 수 없어요. 제약 참고. |
토큰 범위 밖의 엔드포인트에 대한 요청은 HTTP 403을 반환해요. 더 세밀한 범위(리소스별, 또는 읽기 대 쓰기)는 현재 사용할 수 없어요.
권한 경계
페더레이션 규칙의 oauth_scope는 상한이에요. 발행되는 토큰은 결코 그것을 초과할 수 없어요. 대상 서비스 계정의 organization_role(developer 또는 admin)은 어떤 범위가 부여 가능한지 결정하므로, org:admin을 부여하는 규칙은 organization_role=admin인 서비스 계정을 대상으로 해야 해요. 유효 권한은 규칙의 범위와 서비스 계정의 역할의 교집합이에요.
규칙 oauth_scope |
서비스 계정 organization_role |
유효 권한 |
|---|---|---|
workspace:developer |
admin |
규칙의 워크스페이스에서만 Claude API 접근. 범위가 토큰을 역할 아래로 상한 지운다. |
org:admin |
admin |
OAuth 호출자 제외를 뺀 Admin API 전체 접근(조직 구성원, 초대, 워크스페이스, API 키, 그리고 나머지). 제약 참고. |
검증 규칙
Anthropic은 발급자와 규칙을 만들거나 업데이트할 때, 그리고 교환 시 들어오는 JWT를 검증할 때 이 제약들을 강제해요.
전체 파라미터 세부사항과 응답 스키마는 Service accounts API reference, Federation issuers API reference, Federation rules API reference를 참고하세요.
리소스 필드
| 필드 | 제약 |
|---|---|
발급자, 규칙, 서비스 계정 name |
^[a-z0-9-]+$와 일치해야 하고, 길이 1~255자. |
workspace_id |
applies_to_all_workspaces가 true가 아니면 생성 시 필수. 이 규칙 아래 발행되는 토큰에 적용되는 할당량·청구·속도 제한이 있는 워크스페이스(wrkspc_...). 같은 조직의 워크스페이스여야 하고 대상 서비스 계정이 그 워크스페이스의 구성원이어야 한다. |
applies_to_all_workspaces |
불린. 하나를 명명하는 대신 조직의 모든 워크스페이스에서 규칙을 활성화하려면 true로 설정한다. 생성 시 이것 또는 workspace_id 중 하나가 필수다. |
token_lifetime_seconds |
6086400(1분3600. 이 범위 밖의 값은 요청 시 거부된다. 토큰 수명과 갱신 참고. |
URL 필드
issuer_url, jwks.discovery_base, jwks.url 필드는 검증돼요:
| 제약 | 세부내용 |
|---|---|
| 스킴 | https여야 한다. |
| 포트 | 443이어야 한다(명시적 또는 기본). |
| 호스트 | OIDC 공급자의 공개 DNS 호스트 이름이어야 한다. 공개 IP 주소로 해석되어야 하고, IP 리터럴은 받지 않는다. |
URL 검증 실패는 필드 이름을 오류 메시지 접두사로 하여 400 invalid_request_error를 반환해요(예: issuer_url: url must use https scheme).
참고 URL 제약은 Anthropic이 다이얼하는 URL에만 적용돼요.
explicit_url과inlineJWKS 모드, 그리고jwks.discovery_base가 설정된discovery모드에서issuer_url은 JWTiss클레임과 문자열로만 비교되고 절대 가져오지 않으므로, 내부 호스트 이름이나 비표준 포트를 참조할 수 있어요.
JWT 검증
| 제약 | 세부내용 |
|---|---|
| 최대 크기 | assertion JWT는 최대 16KiB여야 한다. |
| 서명 알고리즘 | 비대칭 알고리즘(RSA와 ECDSA 계열: ES256, ES384, ES512, RS256, RS384, RS512, PS256, PS384, PS512)만 받는다. HMAC(HS256, HS384, HS512)와 none은 거부된다. |
| 키 ID | JWT 헤더는 발급자의 JWKS에서 키와 일치하는 kid를 나르야 한다. kid 없는 토큰은 거부된다. |
| 필수 클레임 | sub는 있어야 한다. iat는 있어야 하고 미래가 아니어야 한다. exp는 있어야 하고 미래여야 한다. |
| 단일 사용 | jti 클레임을 나르는 assertion은 발급자당 한 번만 교환할 수 있다. 같은 jti로 교환을 반복하면 리플레이로 거부된다. 발급자의 check_jti 필드(기본 활성화)가 이 검사를 제어하며, jti 클레임이 없는 assertion은 그것에 적용되지 않는다. Federation issuers API reference 참고. |
| 최대 수명 | 토큰의 수명(exp 빼기 iat)은 발급자의 구성된 최대값(기본 1시간, 각 발급자에 대해 Claude Console에서 구성 가능)을 초과해서는 안 된다. |
| 시계 오차 | exp, nbf, iat에 30초 여유가 적용된다. |
규칙 일치 시맨틱
페더레이션 규칙의 match 블록은 들어오는 JWT가 수락되는지 결정해요. 모든 채워진 필드는 AND 시맨틱으로 평가돼요. JWT는 모든 채워진 매처를 충족해야 해요. subject_prefix, claims, condition 중 적어도 하나는 설정되어야 하고, audience만 포함하는(또는 매처가 전혀 없는) match 블록은 거부돼요. 이것은 발급자의 모든 토큰을 받아들이는 규칙을 막기 위한 가드예요.
| 매처 | 타입 | 시맨틱 |
|---|---|---|
subject_prefix |
string | JWT sub 클레임에 대한 정확히 일치. 끝자리 *는 접두사 일치로 만든다(sub 값은 * 앞의 문자들로 시작해야 한다). 대소문자 구분. |
audience |
string | JWT aud 클레임이 이 정확한 문자열을 포함해야 한다. aud가 배열이면 정확히 일치하는 어떤 요소든 검사를 충족한다. |
claims |
map<string, string> | 각 키는 최상위 클레임 이름이고 각 값은 필요한 정확한 문자열 값. 중첩, 숫자, 불린, 또는 목록·맵 같은 복잡한 클레임에는 대신 condition을 CEL 표현식과 함께 사용하세요. |
condition |
string (CEL) | true로 평가되어야 하는 CEL 표현식. |
CEL 평가 환경
condition 표현식은 단일 변수에 접근할 수 있어요:
| 변수 | 타입 | 내용 |
|---|---|---|
claims |
map | 디코딩된 전체 JWT 클레임 집합. 중첩 객체는 중첩 맵으로 접근 가능하다. |
예시:
claims.sub.startsWith("repo:acme-corp/") && claims.ref in ["refs/heads/main", "refs/heads/release"]
경고 CEL 조건은 보안 경계예요. 의도보다 더 많은 입력에 대해
true로 평가되는 표현식은 의도보다 넓은 접근을 부여해요. 제약을 표현할 수 있다면 정적 매처를 선호하세요.
오류
토큰 교환 오류
POST /v1/oauth/token은 표준 API 오류 형태로 오류를 반환해요. SDK는 교환 실패를 HTTP 상태, 응답 본문, request_id를 노출하는 타입화된 FederationExchangeError(또는 언어 등가물)로 감싸요.
| 상태 | 오류 | 원인 | 해결책 |
|---|---|---|---|
| 400 | invalid_request_error |
federation_rule_id가 잘못되었거나 필수 요청 필드가 누락됐다. |
fdrl_ ID와 요청 본문이 모든 필수 필드를 포함하는지 확인하세요. |
| 400 | invalid_request_error |
workspace_id가 있지만 잘 구성된 wrkspc_... ID나 리터럴 default가 아니다. |
workspace_id 값을 고치세요. 응답 메시지가 기대 형식을 명명한다. |
| 401 | authentication_error |
JWT iss 클레임이 등록된 issuer_url과 정확히 같지 않다. |
끝 슬래시와 스킴을 포함해 바이트 단위로 비교하세요: jq -rR 'split(".")[1] | gsub("-";"+") | gsub("_";"/") | @base64d | fromjson | .iss' <<< "$JWT". |
| 401 | authentication_error |
JWKS 가져오기 실패, JWKS가 오래되었거나, JWT가 JWKS에 없는 키로 서명됐다. | inline 모드에서는 회전된 키로 발급자를 업데이트하세요. discovery와 explicit_url에서는 JWKS 엔드포인트가 포트 443에 도달 가능한지 확인하고, 발급자가 최근 서명 키를 회전했다면 키 회전과 캐싱을 참고하세요. |
| 401 | authentication_error |
JWT exp 클레임이 과거다(30초 오차 창을 넘어). |
아이덴티티 공급자가 새 토큰을 프로젝트하고 SDK가 토큰 파일을 다시 읽는지 확인하세요. |
| 401 | authentication_error |
JWT는 검증됐지만 그 클레임이 규칙의 match 블록을 충족하지 않는다. |
JWT를 디코딩해 각 클레임을 규칙과 비교하세요. subject_prefix는 대소문자 구분. audience는 정확한 요소 일치를 요구한다. |
| 401 | authentication_error |
federation_rule_id가 존재하지 않거나, 보관되었거나, JWT가 그것에 대해 승인되지 않았다(열거 방지를 위해 통합). |
Claude Console에서 규칙 ID를 확인하고 규칙이 보관되지 않았는지 확인하세요. |
| 401 | authentication_error |
페더레이션 규칙이 둘 이상의 워크스페이스에 활성화돼 있고 요청이 workspace_id를 생략했다. 인증 기록 항목이 workspace_id_required 이유를 보여준다. |
ANTHROPIC_WORKSPACE_ID(또는 원시 요청의 workspace_id 본문 필드)를 토큰을 범위 지을 wrkspc_... ID로 설정하세요. 토큰 교환 요청 참고. |
모든 assertion 거부는 어떤 검사가 실패했든 고정 메시지 Authentication failed와 함께 같은 불투명한 401 authentication_error를 반환해요. 구분 가능한 오류는 호출자가 규칙 구성을 프로브하게 하기 때문이에요. 거부 이유는 인증 기록의 시도 항목에 기록되는데, 예를 들어 sub 클레임이 규칙의 subject_prefix를 실패하면 match_subject_prefix, 규칙이 여러 워크스페이스에 걸쳐 있고 요청이 아무것도 명명하지 않으면 workspace_id_required예요. 규칙의 조직이 확인되기 전에 거부된 요청(400 invalid_request_error 계열)은 기록 항목을 남기지 않으며, 응답 메시지가 문제를 직접 명명해요. 일치하는 기록 항목이 없는 401은 보통 federation_rule_id 자체가 인식되지 않았다는 뜻이에요.
흔한 SDK 측 실패
| 증상 | 원인 | 해결책 |
|---|---|---|
| SDK가 교환하는 대신 "no credentials"를 보고한다 | ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID, ANTHROPIC_SERVICE_ACCOUNT_ID, 또는 ANTHROPIC_IDENTITY_TOKEN[_FILE] 중 하나가 설정되지 않았고 활성 프로필도 없다. |
네 변수를 모두 설정하거나 프로필을 구성하세요. |
| SDK가 페더레이션하는 대신 API 키로 인증한다 | ANTHROPIC_API_KEY 또는 ANTHROPIC_AUTH_TOKEN이 설정되어 우선순위에서 이긴다. |
키나 토큰 변수를 해제하세요. |
첫 요청에서 FileNotFoundError |
ANTHROPIC_IDENTITY_TOKEN_FILE의 경로가 존재하지 않는다. SDK는 교환 시 파일을 지연 열기한다. |
프로젝티드 토큰 볼륨이 마운트되고 경로가 일치하는지 확인하세요. |
| 토큰 교환은 성공하지만 Claude API 요청이 403을 반환한다 | 발행된 토큰의 범위가 그 엔드포인트에 접근을 부여하지 않는다. | 규칙의 oauth_scope를 OAuth 범위와 비교하세요. |
| 빈 자격 증명으로 인증 실패 | 자격 증명 환경 변수가 내보내졌지만 빈 문자열로 설정됐다. 빈 값도 자기 우선순위 자리를 이긴다. | VAR="" 대신 unset VAR로 변수를 해제하세요. |
실패한 교환 문제 해결
401 authentication_error 응답은 의도적으로 불투명하고 메시지는 항상 Authentication failed예요. 거부 이유는 응답이 아니라 인증 기록에 기록돼요.
팁 Claude Console의 인증 기록 페이지에서 시작하세요. 최근 교환 시도가 평가된 발급자와 규칙, 검사된 JWT 클레임, 실패한 검증 단계를 표면화하며, 대개 다음 검사들을 단축시켜요.
흔한 불투명 실패 하나는 재생된 assertion이에요. jti 클레임을 나르는 assertion은 한 번만 교환될 수 있으므로, 같은 JWT를 다시 보내는 워크로드(재시도 루프, 또는 회전되지 않은 토큰을 다시 읽는 갱신)는 두 번째 교환에서 거부돼요. 인증 기록 페이지는 이 시도들을 jti_reused 이유로 보여주고, 해결책은 교환마다 새 assertion을 발행하는 것이에요.
여전히 JWT 자체에서 디버그해야 한다면 이 검사들을 순서대로 진행하세요:
-
JWT 디코딩 보낸 assertion을 디코딩해 각 클레임을 내 발급자와 규칙 구성과 비교하세요:
jq -rR 'split(".")[1] | gsub("-";"+") | gsub("_";"/") | @base64d | fromjson' <<< "$JWT" -
iss가 발급자와 일치하는지 확인 디코딩된
iss클레임은 스킴, 포트, 끝 슬래시를 포함해 등록된issuer_url과 바이트 단위로 같아야 해요. 단일 문자 불일치가 검증을 실패시켜요. -
aud가 규칙과 일치하는지 확인 디코딩된
aud클레임은 규칙의audience값을 정확한 일치로 포함해야 해요.aud가 배열이면 한 요소가 정확히 일치해야 해요. -
sub와 각 claims 항목 확인
sub를 규칙의subject_prefix와 비교하세요(대소문자 구분, 끝자리*는 접두사 일치, 그 외는 정확히 일치). 규칙의claims맵의 모든 키를 같은 이름의 최상위 클레임과 비교하세요. -
exp, nbf, iat 확인
exp는 미래여야 하고nbf/iat는 30초 오차 창 안에서 과거여야 해요. 워크로드 호스트의 시계가 표류하면 그 외에는 유효한 토큰이 거부돼요. -
JWKS 도달 가능성 확인
discovery모드에서 포트 443의 공개 HTTPS로<jwks.discovery_base or issuer_url>/.well-known/openid-configuration을 가져오고jwks_uri가 해석되는지 확인하세요.explicit_url에서는 JWKS URL을 직접 가져오세요.inline에서는 키 등록 이후 발급자의 서명 키가 회전하지 않았는지 확인하세요.발급자가 서명 키를 회전하고 즉시 그것으로 서명하기 시작하면, Anthropic의 JWKS 캐시가 갱신되는 동안 최대 1분간 교환이 실패할 수 있어요. 키 회전과 캐싱 참고.
JWKS 소스 모드
페더레이션 발급자를 등록할 때 jwks 필드는 Anthropic이 그 발급자의 JWT 서명을 검증하는 데 사용하는 공개 키를 얻는 방법을 제어해요. type을 키로 하는 구분된 합집합이다:
jwks.type |
jwks 형태 |
동작 | 사용 시기 |
|---|---|---|---|
discovery(기본) |
{ "type": "discovery", "discovery_base": "https://..." }(discovery_base는 선택이며, discovery URL이 issuer_url과 다를 때 설정) |
Anthropic이 <discovery_base or issuer_url>/.well-known/openid-configuration을 가져오고, discovery 문서에서 jwks_uri를 읽어 거기서 JWKS를 가져온다. |
IdP가 공개 인터넷에서 표준 OIDC discovery 문서를 제공한다. 대부분의 관리 공급자(EKS, GKE, Cloud Run, GitHub Actions, Entra ID)가 이를 지원한다. |
explicit_url |
{ "type": "explicit_url", "url": "https://..." } |
Anthropic이 url에서 직접 JWKS를 가져온다. issuer_url은 JWT iss 클레임과의 문자열 비교에만 사용되고 절대 다이얼되지 않는다. |
IdP가 discovery 문서를 제공하지 않거나, discovery가 내부 전용이지만 JWKS는 공개적으로 도달 가능할 때. |
inline |
{ "type": "inline", "keys": [...] } |
JWK 객체 배열을 직접 제공한다(JWKS 문서의 keys 배열이지 래퍼 객체가 아님). Anthropic은 아웃바운드 요청을 하지 않는다. issuer_url은 iss 비교에만 사용된다. |
에어갭 환경, 클러스터 내부 발급자 URL을 가진 자체 관리 Kubernetes 클러스터, 또는 키 회전에 대한 명시적 제어를 원할 때. |
구분된 합집합은 보조 필드를 구성적으로 상호 배타적으로 만들어요. discovery와 explicit_url 둘 다 사설 CA로 TLS를 제공하는 발급자를 위한 선택적 ca_cert_pem 문자열도 받아요.
키 회전과 캐싱
discovery와 explicit_url 모드에서 Anthropic은 가져온 JWKS를 캐시해요. 아이덴티티 공급자가 새 서명 키를 게시하고 즉시 그것으로 토큰을 서명하기 시작하면, 그 토큰을 제시하는 교환은 캐시가 갱신되는 동안 최대 1분간 서명 오류로 실패할 수 있어요.
이 창을 피하려면 아이덴티티 공급자가 그것으로 토큰을 서명하기 시작하기 최소 15분 전에 새 서명 키를 JWKS에 게시하고, 교체된 키가 서명한 토큰이 만료될 때까지 그 키를 JWKS에 유지하세요. 관리 아이덴티티 공급자는 보통 스스로 이 규율을 따르는 편이에요. 자체 발급자(자체 관리 Kubernetes 클러스터, SPIRE OIDC discovery 프로바이더, 구성된 회전 주기를 가진 Okta 커스텀 권한 부여 서버)를 운영한다면 회전 정책이 새 키를 첫 사용 전에 게시하는지 확인하세요.
경고
inline모드에서는 자동 키 갱신이 없어요. 아이덴티티 공급자가 서명 키를 회전하면 새 JWKS로 발급자 구성을 업데이트해야 하고, 그렇지 않으면 모든 토큰 교환이 서명 검증을 실패해요.