✨ SSO 로그인용 이벤트 훅
✨ SSO 로그인용 이벤트 훅 (Event Hooks for SSO Login)
Enterprise 기능
SSO에는 LiteLLM Enterprise 라이선스가 필요해요. 무료 30일 체험판을 시작하거나 데모를 예약하세요. Enterprise에 포함된 것 보기. SSO는 최대 5명의 사용자에게 무료예요. 그 이상은 엔터프라이즈 라이선스가 필요해요.
LiteLLM은 인증 설정에 따라 두 가지 다른 SSO 훅을 제공해요.
출처: 문서
본문
| 훅 유형 | 사용 시기 | 동작 |
|---|---|---|
| 커스텀 UI SSO 로그인 핸들러 (Custom UI SSO Sign-in Handler) | LiteLLM 앞에 OAuth 프록시(oauth2-proxy, Gatekeeper, Vouch 등)가 있음 | 요청 헤더에서 사용자 정보를 파싱해 UI에 로그인 |
| 커스텀 SSO 핸들러 (Custom SSO Handler) | 직접 SSO 제공자(Google, Microsoft, SAML)를 사용하고 커스텀 사후 인증 로직을 원함 | 표준 OAuth 플로우 후 커스텀 코드를 실행해 사용자 권한/팀 설정 |
빠른 결정 가이드:
- ✅ 사용자 인증이 LiteLLM 밖(헤더 통해)에서 일어나면 Custom UI SSO Sign-in Handler 사용
- ✅ LiteLLM이 OAuth 플로우를 처리 + 이후 커스텀 로직을 실행하게 하려면 Custom SSO Handler 사용
옵션 1: 커스텀 UI SSO 로그인 핸들러 (Custom UI SSO Sign-in Handler)
LiteLLM 앞에 이미 사용자를 인증하고 요청 헤더를 통해 사용자 정보를 전달하는 OAuth 프록시가 있을 때 사용해요.
동작 방식 (How it works)
- 사용자가 Admin UI에 도착
- 👉 커스텀 SSO 로그인 핸들러가 호출되어 요청 헤더를 파싱하고 사용자 정보 반환
- LiteLLM이 커스텀 핸들러에서 사용자 정보를 검색
- 사용자가 UI에 로그인
사용법 (Usage)
1. 커스텀 UI SSO 핸들러 파일 생성
이 핸들러는 요청 헤더를 파싱하고 OpenID 객체로 사용자 정보를 반환해요:
from fastapi import Request
from fastapi_sso.sso.base import OpenID
from litellm.integrations.custom_sso_handler import CustomSSOLoginHandler
class MyCustomSSOLoginHandler(CustomSSOLoginHandler):
"""
Custom handler for parsing OAuth proxy headers
Use this when you have an OAuth proxy (like oauth2-proxy, Vouch, etc.)
in front of LiteLLM that adds user info to request headers
"""
async def handle_custom_ui_sso_sign_in(
self,
request: Request,
) -> OpenID:
# Parse headers from your OAuth proxy
request_headers = dict(request.headers)
# Extract user info from headers (adjust header names for your proxy)
user_id = request_headers.get("x-forwarded-user") or request_headers.get("x-user")
user_email = request_headers.get("x-forwarded-email") or request_headers.get("x-email")
user_name = request_headers.get("x-forwarded-preferred-username") or request_headers.get("x-preferred-username")
# Return OpenID object with user information
return OpenID(
id=user_id or "unknown",
email=user_email or "[email protected]",
first_name=user_name or "Unknown",
last_name="User",
display_name=user_name or "Unknown User",
picture=None,
provider="oauth-proxy",
)
# Create an instance to be used by LiteLLM
custom_ui_sso_sign_in_handler = MyCustomSSOLoginHandler()
2. config.yaml에서 구성
model_list:
- model_name: "openai-model"
litellm_params:
model: "gpt-5.6-luna"
general_settings:
custom_ui_sso_sign_in_handler: custom_sso_handler.custom_ui_sso_sign_in_handler
litellm_settings:
drop_params: True
set_verbose: True
3. 프록시 시작
$ litellm --config /path/to/config.yaml
4. Admin UI로 이동
사용자가 LiteLLM Admin UI로 이동을 시도하면, 요청이 커스텀 UI SSO 로그인 핸들러로 라우팅돼요.
옵션 2: 커스텀 SSO 핸들러 (사후 인증) (Custom SSO Handler (Post-Authentication))
사용자가 표준 SSO 제공자(Google, Microsoft 등)로 LiteLLM UI에 로그인한 후 자체 코드를 실행하고 싶을 때 사용해요.
동작 방식 (How it works)
- 사용자가 Admin UI에 도착
- LiteLLM이 사용자를 SSO 제공자(Google, Microsoft 등)로 리다이렉트
- SSO 제공자가 사용자를 LiteLLM으로 리다이렉트
- LiteLLM이 IDP에서 사용자 정보를 검색
- 👉 커스텀 SSO 핸들러가 호출되고
SSOUserDefinedValues타입의 객체 반환 - 사용자가 UI에 로그인
사용법 (Usage)
1. 커스텀 SSO 핸들러 파일 생성
응답 타입이 SSOUserDefinedValues pydantic 객체를 따르도록 하세요. 이는 사용자를 Admin UI에 로그인시키는 데 사용돼요:
from fastapi_sso.sso.base import OpenID
from litellm.proxy._types import LitellmUserRoles, SSOUserDefinedValues
from litellm.proxy import proxy_server
# These imports are available if you need to create users or manage team membership:
# from litellm.proxy.management_endpoints.internal_user_endpoints import new_user
# from litellm.proxy.management_endpoints.team_endpoints import add_new_member
async def custom_sso_handler(userIDPInfo: OpenID) -> SSOUserDefinedValues:
try:
print("inside custom sso handler") # noqa
print(f"userIDPInfo: {userIDPInfo}") # noqa
if userIDPInfo.id is None:
raise ValueError(
f"No ID found for user. userIDPInfo.id is None {userIDPInfo}"
)
#################################################
# Access extra fields from SSO provider (requires GENERIC_USER_EXTRA_ATTRIBUTES env var)
# Example: Set GENERIC_USER_EXTRA_ATTRIBUTES="department,employee_id,groups"
extra_fields = getattr(userIDPInfo, 'extra_fields', None) or {}
user_department = extra_fields.get("department")
employee_id = extra_fields.get("employee_id")
user_groups = extra_fields.get("groups", [])
print(f"User department: {user_department}") # noqa
print(f"Employee ID: {employee_id}") # noqa
print(f"User groups: {user_groups}") # noqa
#################################################
#################################################
# Run your custom code / logic here
# check if user exists in litellm proxy DB
if proxy_server.prisma_client is not None:
_user_info = await proxy_server.prisma_client.get_data(user_id=userIDPInfo.id)
print("_user_info from litellm DB ", _user_info) # noqa
#################################################
return SSOUserDefinedValues(
models=[], # models user has access to
user_id=userIDPI...
2. config.yaml에서 구성
파일 경로를 config.yaml에 전달하세요.
예를 들어 둘 다 같은 디렉토리에 있다면 - ./config.yaml과 ./custom_sso.py - 다음과 같아요:
model_list:
- model_name: "openai-model"
litellm_params:
model: "gpt-5.6-luna"
general_settings:
custom_sso: custom_sso.custom_sso_handler
litellm_settings:
drop_params: True
set_verbose: True
3. 프록시 시작
$ litellm --config /path/to/config.yaml