Hugging Face로 로그인하기
Hugging Face로 로그인하기 (Sign in with Hugging Face)
HF OAuth / OpenID Connect 흐름을 쓰면 어떤 웹사이트나 앱에도 "Sign in with HF" 버튼을 쉽게 넣을 수 있어요. 사용자가 자신의 HF 계정으로 로그인하도록 유도하는 가장 표준적인 방법이죠.
출처: 문서
본문
HF OAuth / OpenID Connect 흐름을 사용하면 어떤 웹사이트나 앱에도 "Hugging Face로 로그인" 흐름을 만들 수 있어요. 이렇게 하면 사용자가 HF 계정으로 버튼 하나만 눌러 로그인할 수 있습니다.
버튼을 누르면 사용자에게 앱을 승인할 권한 모달(permissions modal)이 표시됩니다.

OAuth 앱 만들기 (Creating an oauth app)
애플리케이션은 설정에서 만들 수 있어요.

공개 OAuth 앱 (비밀번호 없음, Public OAuth apps)
클라이언트 시크릿 없이도 OAuth 앱을 만들거나 사용할 수 있어요. 네이티브 앱, CLI, 또는 시크릿을 안전하게 보관하기 어려운 환경에 유용합니다.
- 앱 생성 시: 새 OAuth 앱을 만들 때 시크릿 없이 만들도록 선택할 수 있어요.
- 생성 후: 기존 앱의 앱 설정에서 클라이언트 시크릿을 삭제하면 공개 앱으로 동작합니다.
공개 앱은 클라이언트 ID만으로 인증합니다(예: device code 흐름이나 PKCE를 쓰는 authorization code 흐름). 시크릿이 있는 앱은 필요할 때 여전히 시크릿을 사용할 수 있어요.
리다이렉트 URI (Redirect URIs)
인증 요청에 보내는 redirect_uri는 앱에 등록된 리다이렉트 URI 중 하나와 정확히 일치해야 합니다.
루프백(loopback) 리다이렉트 URI는 한 가지 예외: 루프백 호스트(localhost, 127.0.0.1, [::1])의 http 스킴을 쓰는 URI는 다른 모든 구성이 등록된 URI와 일치하기만 하면 요청 시점에 어떤 포트든 허용됩니다. 이는 RFC 8252 §7.3 / OAuth 2.1을 따르는 것으로, 네이티브 앱·CLI·MCP 클라이언트가 http://localhost/callback 같은 포트 없는 URI를 등록하고 운영체제가 할당하는 임시 포트(예: http://localhost:49282/callback)에서 대기하도록 해줍니다.
몇 가지 유의할 점:
- 예외는
http스킴에만 적용돼요.https와 커스텀 스킴(예:myapp://callback) 리다이렉트 URI는 포트를 포함해 항상 정확히 일치해야 합니다. - 루프백 호스트는 개별적으로 매칭됩니다.
http://localhost:49282/callback요청은 등록된http://127.0.0.1/callback과 매칭되지 않아요. 둘 다 쓸 수 있다면 둘 다 등록하세요. - 포트만 달라질 수 있어요. 경로, 쿼리, userinfo는 여전히 정확히 일치해야 합니다.
Spaces에 호스팅하는 경우 (If you are hosting in Spaces)
[!TIP] 앱을 Spaces에 호스팅하면 흐름 구현이 훨씬 쉬워집니다(그리고 Gradio에 바로 내장되어 있어요). Spaces OAuth 가이드를 확인해 보세요.
자동 OAuth 앱 생성 (Automated oauth app creation)
Hugging Face는 CIMD(Client ID Metadata Documents)를 지원해서 웹사이트용 OAuth 앱을 자동으로 만들 수 있어요:
- 웹사이트에
/.well-known/oauth-cimd엔드포인트를 추가해 다음 JSON을 반환하게 하세요:
{
client_id: "[your website url]/.well-known/oauth-cimd",
client_name: "Your Website",
redirect_uris: ["[your website url]/oauth/callback/huggingface"],
token_endpoint_auth_method: "none",
logo_uri: "https://....", // optional
client_uri: "[your website url]", // optional
}
"[your website url]/.well-known/oauth-cimd"를 클라이언트 ID로, PCKE를 인증 메커니즘으로 사용하세요.
로컬 포트에서 authorization code를 받는 네이티브 앱과 MCP 클라이언트는 redirect_uris에 포트 없는 루프백 URI를 나열할 수 있어요. 예: ["http://localhost/callback", "http://127.0.0.1/callback"] — Redirect URIs 참고.
이 기능은 임시 환경이나 MCP 클라이언트에서 특히 유용해요. Hugging Chat의 구현 예시를 참고하세요.
디바이스 코드 OAuth (Device code OAuth)
디바이스 코드 흐름을 쓰면 사용자가 한 기기(예: CLI)에서 앱을 승인하고, 다른 기기(예: 폰이나 브라우저)에 짧은 코드를 입력해서 승인을 완료할 수 있어요. 앱이 실행 중인 기기에 리다이렉트 URI나 브라우저가 필요 없습니다.


예제 스크립트로 테스트하기 (Testing with a sample script)
다음 스크립트로 디바이스 코드 OAuth 앱을 테스트할 수 있어요. <Client ID>를 앱의 클라이언트 ID로 바꾸세요. 공개 앱(시크릿 없음)은 스크립트를 그대로 쓸 수 있어요. 시크릿이 있는 앱은 device 요청과 token 요청 양쪽에 Authorization: Basic 헤더(client_id:client_secret의 Base64)를 추가하세요.
#!/bin/bash
CLIENT_ID="<Client ID>"
# Step 1: Get device code
RESPONSE=$(curl -s -X POST https://huggingface.co/oauth/device \
-d "client_id=$CLIENT_ID")
DEVICE_CODE=$(echo $RESPONSE | jq -r '.device_code')
USER_CODE=$(echo $RESPONSE | jq -r '.user_code')
VERIFICATION_URI=$(echo $RESPONSE | jq -r '.verification_uri')
echo "Device Code: $DEVICE_CODE"
echo "User Code: $USER_CODE"
echo ""
echo "Open: ${VERIFICATION_URI}"
echo "Enter the user code: $USER_CODE"
echo ""
read -p "Press Enter after authorizing..."
# Step 3: Get token
curl -X POST https://huggingface.co/oauth/token \
-d "grant_type=urn:ietf:params:oauth:grant-type:device_code" \
-d "device_code=$DEVICE_CODE" \
-d "client_id=$CLIENT_ID"
[!NOTE] 클라이언트 시크릿이 있는 OAuth 앱은 device code 요청과 token 요청 양쪽에
Authorization: Basic헤더(Base64로 인코딩된client_id:client_secret)를 포함해야 해요.
현재 지원되는 스코프 (Currently supported scopes)
현재 지원되는 스코프는 다음과 같아요:
openid: access token에 더해 ID token을 받습니다.profile: 사용자 프로필 정보(사용자명, 아바타 등)를 읽습니다.email: 사용자의 이메일 주소를 읽습니다.read-billing: 사용자가 결제 수단을 설정했는지 알 수 있습니다.read-memberships: 사용자가 속한 조직과 각 조직에서의 역할을 읽습니다. 조직의 설정이나 리소스 접근 권한은 부여하지 않아요.read-repos: 사용자의 개인 리포지토리를 읽습니다.gated-repos: 사용자가 접근 권한을 받은 공개 gated 리포지토리의 내용을 읽습니다.read-repos와 달리 비공개 리포지토리 접근은 부여하지 않아요.contribute-repos: 리포지토리를 만들고 이 앱이 만든 리포지토리에 접근합니다. 추가 권한을 받지 않는 한 다른 리포지토리에는 접근할 수 없어요.write-repos: 사용자의 개인 리포지토리를 읽고 씁니다.manage-repos: 만들기와 삭제를 포함해 사용자의 개인 리포지토리를 완전히 관리합니다.read-collections: 사용자의 개인 컬렉션을 읽습니다.write-collections: 만들기와 삭제를 포함해 사용자의 개인 컬렉션을 읽고 씁니다.inference-api: 사용자를 대신해 Inference Providers에 inference 요청을 보냅니다.read-endpoints: 사용자의 Inference Endpoints를 보고 사용자를 대신해 inference 요청을 보냅니다.write-endpoints: 만들기와 삭제를 포함해 사용자의 Inference Endpoints를 관리합니다.read-endpoints접근을 포함합니다.jobs: jobs를 실행합니다.webhooks: webhooks를 관리합니다.write-discussions: 사용자를 대신해 discussions와 Pull Requests를 열고, reactions, 댓글 작성/수정, discussion 닫기 등과 상호작용합니다. 비공개 리포지토리에 Pull Requests를 열려면read-repos스코프도 요청해야 해요.
그 외의 모든 정보는 OpenID 메타데이터에서 확인할 수 있어요.
[!WARNING] 추가 스코프가 필요하면 저희에게 연락해 주세요.
조직 리소스 접근 (Accessing organization resources)
기본적으로 OAuth 앱은 조직 리소스에 접근할 필요가 없어요.
하지만 read-repos나 read-billing 같은 일부 스코프는 조직에도 적용됩니다.
사용자는 앱을 승인할 때 접근을 허용할 조직을 선택할 수 있어요. 특정 조직에 접근이 필요하면 OAuth 승인 URL에 orgIds=ORG_ID 쿼리 파라미터를 추가하면 됩니다. ORG_ID는 userinfo 응답의 organizations.sub 필드에서 확인할 수 있는 조직 ID로 바꿔야 해요.
브랜딩 (Branding)
버튼 디자인은 자유롭게 만들 수 있어요. 아래는 유용하게 제공되는 SVG 이미지들입니다.
badges 페이지에서 markdown이나 HTML에 통합하는 방법과 함께 확인해 보세요.
조직용 토큰 교환 (RFC 8693, Token Exchange for Organizations)
[!WARNING] 이 기능은 Enterprise 플랜에 포함돼 있어요.
Token Exchange를 쓰면 조직이 대화형 사용자 동의 없이 프로그램적으로 멤버용 access token을 발급할 수 있어요. 조직 멤버를 대신해 Hugging Face 리소스에 접근해야 하는 내부 도구, 자동화 파이프라인, 엔터프라이즈 통합을 만들 때 특히 유용합니다.
[!TIP] 멤버별 토큰 발급 없이 CI/CD 워크플로(GitHub Actions, GitLab CI, CircleCI 등)에서 키 없는 인증만 필요하다면 Trusted Publishers를 참고하세요. 이 역시
/oauth/token을 사용하지만 CI 제공자가 발급한 OIDCid_token을 subject token으로 씁니다(Enterprise 플랜 불필요, 클라이언트 자격증명 불필요).
이 기능은 토큰 교환 시나리오의 표준 프로토콜인 RFC 8693 - OAuth 2.0 Token Exchange를 구현합니다.
사용 사례 (Use cases)
Token Exchange는 다음과 같은 시나리오를 위해 설계됐어요:
- 내부 플랫폼 구축: 팀 멤버가 각자 수동으로 인증하지 않아도 팀 멤버를 대신해 Hugging Face 리소스에 접근하는 대시보드나 포털을 만듭니다.
- CI/CD 파이프라인 자동화: 조직 리포지토리에 모델이나 데이터셋을 올려야 하는 자동화 워크플로용 단기·스코프된 토큰을 발급합니다.
- 엔터프라이즈 ID 시스템 통합: 내부 사용자 디렉터리를 기반으로 토큰을 발급해 기존 ID 제공자와 Hugging Face를 연결합니다.
- 커스텀 접근 제어 구현: 조직의 내부 정책에 따라 특정 스코프로 토큰을 발급하는 미들웨어를 만듭니다.
동작 방식 (How it works)
- 조직에
token-exchange권한이 있는 OAuth 애플리케이션을 바인딩합니다. - 백엔드 서비스가 클라이언트 자격증명으로 이 OAuth 앱에 인증합니다.
- 서비스가 특정 조직 멤버(이메일로 식별)의 access token을 요청합니다.
- Hugging Face가 사용자가 조직의 멤버인지 확인하고 스코프된 토큰을 발급합니다.
- 발급된 토큰은 조직 스코프 안의 리소스에만 접근할 수 있습니다.
사전 요구사항 (Prerequisites)
Token Exchange를 쓰려면 token-exchange 권한이 있는 조직 바인딩 OAuth 애플리케이션이 필요해요. 조직에 적격한 OAuth 앱을 설정하려면 Hugging Face 지원팀에 문의하세요.
설정이 끝나면 다음을 받게 됩니다:
- Client ID (예:
a1b2c3d4-e5f6-7890-abcd-ef1234567890) - Client Secret (안전하게 보관하세요!)
[!WARNING] 조직 관리자는 생성 후 OAuth 앱을 관리할 수 있어요. 클라이언트 시크릿 갱신과 토큰 유효기간 설정이 포함됩니다.
인증 (Authentication)
Token Exchange는 OAuth 앱 자격증명으로 HTTP Basic Authentication을 사용합니다. client_id:client_secret을 Base64로 인코딩해 authorization 헤더를 만드세요:
# Create the authorization header
export CLIENT_ID="your-client-id"
export CLIENT_SECRET="your-client-secret"
export AUTH_HEADER=$(echo -n "${CLIENT_ID}:${CLIENT_SECRET}" | base64)
이메일로 토큰 발급하기 (Issuing tokens by email)
조직 멤버의 이메일 주소로 access token을 발급하려면:
curl -X POST "https://huggingface.co/oauth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Authorization: Basic ${AUTH_HEADER}" \
-d "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
-d "[email protected]" \
-d "subject_token_type=urn:huggingface:token-type:user-email"
응답 (Response)
성공적인 요청은 access token을 반환합니다:
{
"access_token": "hf_oauth_...",
"token_type": "bearer",
"expires_in": 28800,
"scope": "openid profile email read-repos",
"id_token": "eyJhbGciOiJS...",
"issued_token_type": "urn:ietf:params:oauth:token-type:access_token"
}
id_token 필드는 openid 스코프를 요청했을 때 포함됩니다.
이 토큰을 사용해 사용자를 대신해 API 요청을 보낼 수 있어요:
curl "https://huggingface.co/api/whoami-v2" \
-H "Authorization: Bearer ${TOKEN}"
스코프 제어 (Scope control)
기본적으로 발급된 토큰은 OAuth 앱에 구성된 모든 스코프를 상속합니다. scope 파라미터를 추가해 특정 스코프를 요청할 수 있어요. 사용 가능한 값은 Currently supported scopes를 참고하세요.
토큰의 유효 권한은 요청된 스코프와 사용자의 조직 내 역할 양쪽에 의해 제한됩니다.
curl -X POST "https://huggingface.co/oauth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "Authorization: Basic ${AUTH_HEADER}" \
-d "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
-d "[email protected]" \
-d "subject_token_type=urn:huggingface:token-type:user-email" \
-d "scope=openid profile"
[!TIP] 최소 권한 원칙을 따르세요. 애플리케이션이 실제로 필요한 스코프만 요청하세요.
보안 고려사항 (Security considerations)
Token Exchange로 발급된 토큰에는 보안 제한이 내장돼 있어요:
- 조직 스코프: 토큰은 조직이 소유한 리소스(모델, 데이터셋, Spaces, 컬렉션) 안에서만 접근할 수 있어요. 조직 밖에서는 읽기 전용이며, 어떤 사용자/조직의 공개 컬렉션과 사용자가 개별적으로 접근 권한을 받은 공개 gated 리포지토리로 제한됩니다.
- 개인 접근 없음: 토큰은 사용자의 개인 비공개 리포지토리나 다른 조직의 비공개 리포지토리에 접근할 수 없어요.
- 단기 유효: 토큰은 기본적으로 8시간 후 만료됩니다. 조직 관리자는 OAuth 앱 설정에서 토큰 유효기간(최대 30일)을 구성할 수 있어요. refresh token은 제공되지 않습니다.
- 감사 가능: 모든 토큰 교환은 기록되며 조직의 audit logs에 표시됩니다.
[!WARNING] OAuth 앱 자격증명을 안전하게 보호하세요. 클라이언트 시크릿에 접근할 수 있는 사람은 조직의 모든 멤버를 위해 토큰을 발급할 수 있어요.
오류 응답 (Error responses)
| Error | Description |
|---|---|
invalid_client |
클라이언트가 토큰 교환 권한이 없거나 앱이 조직에 바인딩되지 않음 |
invalid_grant |
바인딩된 조직에서 사용자를 찾을 수 없음 |
invalid_scope |
요청한 스코프가 유효하지 않음 |
참고 (Reference)
Grant type:
urn:ietf:params:oauth:grant-type:token-exchange
요청 파라미터 (subject_token_type):
| Value | Description |
|---|---|
urn:huggingface:token-type:user-email |
이메일 주소로 사용자 식별 |
응답 필드 (issued_token_type):
| Value | Description |
|---|---|
urn:ietf:params:oauth:token-type:access_token |
access token이 발급됐음을 나타냄 |
관련 문서:
더 알아보기 (Learn more)
OAuth 앱을 만들고 나면 Spaces OAuth 가이드와 Trusted Publishers, 그리고 사용자 프로필·멤버십을 읽어오는 스코프 조합을 함께 살펴보는 걸 추천해요. 실제 동작 예시는 Hugging Chat의 구현 PR을 참고할 수 있습니다.