Oracle Cloud Infrastructure용 워크로드 아이덴티티 페더레이션 구성
Oracle Cloud Infrastructure용 워크로드 아이덴티티 페더레이션 구성 (Configuring workload identity federation for Oracle Cloud Infrastructure)
Oracle Identity Cloud Service(IDCS) 액세스 토큰을 수명이 짧은 OpenAI 액세스 토큰으로 교환해 Oracle Cloud Infrastructure(OCI)를 Workload Identity Provider로 써요. OCI 인스턴스 프린시펄이 같은 테넌시의 아이덴티티 도메인에 토큰 교환 요청을 서명해요. OpenAI가 결과 토큰을 검증하고 OCI 워크로드가 매핑된 OpenAI 서비스 계정으로 동작하도록 승인해요.
이 설정은 OpenAI API 키, 커스텀 Oracle OAuth 리소스 애플리케이션, 커스텀 애플리케이션에 대한 동적 그룹 grant가 필요하지 않아요.
출처: 문서
본문
OCI 워크로드 설정
인스턴스 프린시펄로 OCI Compute 인스턴스에서 워크로드를 실행해요. Oracle Kubernetes Engine(OKE)에서는 요청에 서명하는 아이덴티티를 확인하세요. 표준 인스턴스 프린시펄 서명자는 일반적으로 개별 Kubernetes pod가 아니라 워커 노드를 식별해요. 서명자는 OCI 인스턴스 메타데이터 서비스에서 자격증명을 얻어요. 워크로드가 링크-로컬 메타데이터 엔드포인트에 도달할 수 있는지 확인하세요.
curl --fail --silent \
--header "Authorization: Bearer Oracle" \
http://169.254.169.254/opc/v2/instance/id
워크로드는 또한 테넌시의 아이덴티티 도메인으로 아웃바운드 HTTPS 요청을 할 수 있어야 해요. 메타데이터 엔드포인트 자체는 NAT 게이트웨이나 인터넷 연결을 요구하지 않아요.
Oracle 아이덴티티 토큰 요청
OCI Python SDK의 InstancePrincipalsSecurityTokenSigner로 아이덴티티 도메인에 OAuth 토큰 교환 요청을 서명해요.
POST https://<identity-domain>/oauth2/v1/token
Content-Type: application/x-www-form-urlencoded;charset=utf-8
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
scope=urn:opc:idm:__myscopes__
requested_token_type=urn:ietf:params:oauth:token-type:access_token
urn:opc:idm:__myscopes__ 스코프는 인스턴스 프린시펄의 기존 권한을 사용해요. 반환된 IDCS 액세스 토큰을 OpenAI 워크로드 아이덴티티 페더레이션의 subject 토큰으로 써요. Oracle 토큰 audience를 https://api.openai.com/v1로 대체하지 마세요. OpenAI provider에는 실제 Oracle 토큰에 나타나는 audience로 구성하세요.
토큰 검증
TOKEN을 실제 OCI 워크로드가 생성한 액세스 토큰으로 설정하고, 기존 로컬 JWT 디코더(Python)로 클레임을 검사해요.
import base64
import json
import os
import re
def reject_non_json_constant(value):
raise ValueError(f"JWT payload contains non-JSON constant: {value}")
parts = os.environ.get("TOKEN", "").split(".")
if len(parts) != 3:
raise ValueError("Expected a compact JWT with three segments")
payload = parts[1]
if re.fullmatch(r"[A-Za-z0-9_-]+", payload) is None or len(payload) % 4 == 1:
raise ValueError("JWT payload is not valid Base64URL")
padded_payload = payload + "=" * (-len(payload) % 4)
decoded = base64.b64decode(padded_payload, altchars=b"-_", validate=True)
if base64.urlsafe_b64encode(decoded).rstrip(b"=").decode("ascii") != payload:
raise ValueError("JWT payload is not valid Base64URL")
decoded_text = decoded.decode("utf-8")
claims = json.loads(decoded_text, parse_constant=reject_non_json_constant)
if not isinstance(claims, dict):
raise ValueError("JWT payload is not a JSON object")
print(decoded_text)
이 명령은 서명 검증 없이 JWT 페이로드를 디코딩해요. 프로덕션 토큰은 로컬 디코더를 쓰고 제3자 도구에 붙여넣지 마세요.
워크로드 아이덴티티 페더레이션 설정
Oracle 아이덴티티 도메인 발급자를 위한 OpenAI Workload Identity Provider를 만든 뒤, 디코딩된 토큰의 안정적인 클레임과 일치하는 서비스 계정 매핑을 추가해요. Workload Identity Provider를 먼저 구성해요.
Workload Identity Provider 설정
- Workload Identity Provider를 만든다. Name은
oci-workload-identity-prod같은 고유 값, Description은Production OCI workloads. - 발급자와 audience를 설정한다. OIDC Issuer URL에 디코딩된 Oracle 토큰의
iss값. Audience에는 실제 Oracle 토큰aud클레임에 나타나는 값을. - 공개 JWKS를 검증에 쓴다. Use uploaded JWKS for token verification을 켜고 JWKS JSON을 Oracle 아이덴티티 도메인의 공개 JWKS로 설정해요. 올바른 발급자·공개 키가 등록되면 Oracle IDCS가 서명 키를 OIDC discovery(
/.well-known/openid-configuration)로 노출할 수도 있지만, OpenAI의 기본 OIDC discovery가 이 흐름에 항상 동작하는 것은 아니므로 로컬 JWKS 모드가 더 안정적일 수 있어요. 키 회전 시 업로드된 JWKS를 갱신하세요. - 유도 매핑 속성이 필요할 때만 속성 변환을 추가한다. raw 토큰 클레임은 매핑에 직접 쓸 수 있어요. 변환을 만들면 대시보드가
openai.접두사를 자동 적용해요. raw 토큰 클레임이 이미openai.로 시작하면 일치하는 변환 없이는openai.매핑 키에 무시돼요.
서비스 계정 매핑 설정
- 서비스 계정 매핑을 만든다. Name은 provider 안에서 고유한
oci-openai-wif같은 값. - Oracle 아이덴티티를 일치시킨다. 디코딩된 토큰에서 안정적인 클레임으로 Key·Value 행을 추가해요. 인스턴스 프린시펄은 일반적으로
sub에 OCI 주체 형식(Oracle-Native 형식의<ocid>이나 사용자/그룹 주체의 combo 주체)을 가져요. 실제 디코딩된 토큰을 기준으로 정확한 값으로 매칭해요. - OpenAI 대상을 고른다. Project는 대상 서비스 계정을 소유한 프로젝트, Service account는 OCI 워크로드가 쓸 수 있는 서비스 계정.
- 필요하면 API 권한을 좁힌다.
api.model.request,api.vector_store.read같은 Permissions를 선택하거나 비워 둔다.
코드에서 토큰 사용
OpenAI SDK 클라이언트가 OCI 인스턴스 프린시펄 토큰을 얻어 OpenAI 액세스 토큰으로 교환하도록 구성해요. SDK 예시는 OCI 인스턴스 프린시펄 서명으로 IDCS 액세스 토큰을 요청하고, 그 토큰을 subject token으로 OpenAI X509/OIDC 워크로드 아이덴티티에 넘겨요.
Python 예시는 OCI Python SDK와 OpenAI SDK를 결합해요. OCI SDK로 InstancePrincipalsSecurityTokenSigner을 구성하고 identity domain URL을 지정해 token exchange를 호출하고 access_token을 받아요. 그 액세스 토큰을 OpenAI 클라이언트의 subject token provider로 넘겨 OpenAI 발행 액세스 토큰으로 교환한 뒤 responses.create를 호출해요.
# 요청 흐름 요약
1. OCI 인스턴스 프린시펄로 IDCS 토큰 교환 → IDCS access_token
2. OpenAI: workload_identity { identity_provider_id, service_account_id, provider: { token_type="jwt", get_token=IDCS_access_token } }
3. client.responses.create(...)
Oracle Cloud 베스트 프랙티스
- 각 워크로드에 전용 인스턴스 프린시펄·서비스 계정 사용. 무관한 환경 간 아이덴티티 공유 금지.
- 실제 Oracle 토큰에 나타나는 audience로 OpenAI provider를 구성. audience를 임의로 바꾸지 마세요.
- 키 회전에 맞춰 업로드된 JWKS를 최신으로 유지. 구성된 JWKS에 없는 키로 서명된 토큰은 거부돼요.
- 정확한 클레임 매칭 선호.
sub같은 안정적 클레임으로 매칭해 우발적 접근을 막아요. - 프로덕션·비프로덕션 워크로드 분리. 매핑을 환경 경계에 맞춰 범위 지정.
- 워크로드가 필요한 권한만 부여. 매핑 수준 권한으로 대상 서비스 계정이 주는 접근을 더 좁혀요.
더 알아보기 (Learn more)
워크로드 아이덴티티 페더레이션의 공통 개념은 메인 문서를 참고하세요. OCI 인스턴스 프린시펄에 대한 자세한 내용은 OCI 설명서를 참고하세요.