Skip to content

SSO और OAuth प्रमाणीकरण

Potato में Google, GitHub, HuggingFace और जेनेरिक OIDC लॉगिन कॉन्फ़िगर करें। ईमेल डोमेन या GitHub संगठन के आधार पर पहुंच सीमित करें, और SSO को स्थानीय पासवर्ड लॉगिन के साथ चलाएं।

v2.3.0 में नया

डिफ़ॉल्ट रूप से, Potato एक सरल उपयोगकर्तानाम-आधारित लॉगिन का उपयोग करता है, जिसमें एनोटेटर साइन इन करने के लिए कोई भी उपयोगकर्तानाम टाइप करते हैं। यह स्थानीय विकास और छोटे प्रोजेक्टों के लिए ठीक है, लेकिन प्रोडक्शन तैनाती को अनधिकृत पहुंच रोकने, एनोटेटर की पहचान की पुष्टि करने और संस्थागत आवश्यकताओं को पूरा करने के लिए उचित प्रमाणीकरण चाहिए।

SSO एक ही जगह कॉन्फ़िगर होता है। authentication.method को oauth पर सेट करें, फिर authentication.providers के अंतर्गत एक या अधिक प्रोवाइडर सूचीबद्ध करें। हर प्रोवाइडर को लॉगिन पेज पर अपना अलग बटन मिलता है।

Potato में तीन प्रोवाइडरों के लिए अंतर्निहित एंडपॉइंट मेटाडेटा है: google, github और huggingface। कोई भी अन्य प्रोवाइडर नाम जेनेरिक OIDC माना जाता है और उसे discovery_url की ज़रूरत होती है।

त्वरित शुरुआत

एक न्यूनतम Google सेटअप:

yaml
authentication:
  method: "oauth"
  providers:
    google:
      client_id: ${GOOGLE_CLIENT_ID}
      client_secret: ${GOOGLE_CLIENT_SECRET}
  user_identity_field: "email"
 
secret_key: ${POTATO_SECRET_KEY}

सीक्रेट्स को फ़ाइल में रखने के बजाय एनवायरनमेंट में सेट करें:

bash
export GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
export GOOGLE_CLIENT_SECRET="your-client-secret"
export POTATO_SECRET_KEY="$(python3 -c 'import secrets; print(secrets.token_hex(32))')"

secret_key एक टॉप-लेवल कुंजी है, यह authentication ब्लॉक का हिस्सा नहीं है। इसे सेट करें, या POTATO_SECRET_KEY सेट करें। जब दोनों में से कोई भी मौजूद नहीं होता, तो Potato एक रैंडम कुंजी बनाता है, जिसका अर्थ है कि हर रीस्टार्ट सभी सत्रों को अमान्य कर देता है, और OAuth इसके बिना कॉन्फ़िगर होने पर वह एक चेतावनी लॉग करता है।

Potato दो OAuth रूट देता है। /auth/login/<provider> फ़्लो शुरू करता है और /auth/callback/<provider> प्रतिक्रिया प्राप्त करता है। कॉलबैक वह URL है जिसे आप प्रोवाइडर के पास रजिस्टर करते हैं, इसलिए Google के लिए यह https://your-domain.com/auth/callback/google है। कोई redirect_uri कॉन्फ़िग कुंजी नहीं है; रूट प्रोवाइडर के नाम से बनता है।

Google

Google Cloud Console में "Web application" प्रकार के OAuth 2.0 क्रेडेंशियल बनाएं, और https://your-domain.com/auth/callback/google को अधिकृत रीडायरेक्ट URI के रूप में जोड़ें। स्थानीय विकास के लिए http://localhost:8000/auth/callback/google स्वीकार किया जाता है।

yaml
authentication:
  method: "oauth"
  providers:
    google:
      client_id: ${GOOGLE_CLIENT_ID}
      client_secret: ${GOOGLE_CLIENT_SECRET}
      allowed_domain: "umich.edu"

allowed_domain एक ही डोमेन स्ट्रिंग लेता है। केवल वे खाते साइन इन कर सकते हैं जिनका ईमेल उस डोमेन में है।

GitHub

GitHub Settings > Developer settings > OAuth Apps के अंतर्गत एक OAuth ऐप रजिस्टर करें, और कॉलबैक URL को https://your-domain.com/auth/callback/github पर सेट करें।

yaml
authentication:
  method: "oauth"
  providers:
    github:
      client_id: ${GITHUB_CLIENT_ID}
      client_secret: ${GITHUB_CLIENT_SECRET}
      allowed_org: "my-research-lab"

allowed_org एक ही संगठन का नाम लेता है। इसके सेट होने पर Potato अपने आप read:org स्कोप का अनुरोध करता है, इसलिए आपको स्कोप खुद सूचीबद्ध करने की ज़रूरत नहीं है। जांच को सदस्यता दिखे, इसके लिए एनोटेटर की संगठन में सदस्यता सार्वजनिक होनी चाहिए।

HuggingFace

huggingface.co/settings/applications पर एक OAuth एप्लिकेशन बनाएं।

yaml
authentication:
  method: "oauth"
  providers:
    huggingface:
      client_id: ${HF_CLIENT_ID}
      client_secret: ${HF_CLIENT_SECRET}
  user_identity_field: "username"

HuggingFace प्रोवाइडर HuggingFace के OIDC डिस्कवरी एंडपॉइंट से जुड़ता है और डिफ़ॉल्ट रूप से openid profile email का अनुरोध करता है।

जेनेरिक OIDC

google, github और huggingface के अलावा कोई भी प्रोवाइडर नाम जेनेरिक OIDC माना जाता है और उसके लिए discovery_url आवश्यक है। इसे एक display_name दें ताकि लॉगिन बटन पढ़ने योग्य रहे।

yaml
authentication:
  method: "oauth"
  providers:
    oidc:
      display_name: "University SSO"
      discovery_url: "https://sso.university.edu/.well-known/openid-configuration"
      client_id: ${OIDC_CLIENT_ID}
      client_secret: ${OIDC_CLIENT_SECRET}
      scopes:
        - "openid"
        - "email"
        - "profile"

प्रोवाइडर के पास रजिस्टर किया जाने वाला कॉलबैक URL प्रोवाइडर कुंजी के अनुसार होता है, इसलिए oidc नाम का ब्लॉक https://your-domain.com/auth/callback/oidc का उपयोग करता है।

सामान्य प्रोवाइडरों के डिस्कवरी URL:

प्रोवाइडरडिस्कवरी URL
Oktahttps://your-org.okta.com/.well-known/openid-configuration
Azure ADhttps://login.microsoftonline.com/{tenant-id}/v2.0/.well-known/openid-configuration
Auth0https://your-domain.auth0.com/.well-known/openid-configuration
Keycloakhttps://keycloak.example.com/realms/{realm}/.well-known/openid-configuration

scopes का डिफ़ॉल्ट मान ["openid", "email", "profile"] है।

एकाधिक प्रोवाइडर

providers में जितनी चाहें उतनी प्रविष्टियां हो सकती हैं, और हर एक अपना लॉगिन बटन दिखाती है।

yaml
authentication:
  method: "oauth"
  providers:
    google:
      client_id: ${GOOGLE_CLIENT_ID}
      client_secret: ${GOOGLE_CLIENT_SECRET}
    github:
      client_id: ${GITHUB_CLIENT_ID}
      client_secret: ${GITHUB_CLIENT_SECRET}
    oidc:
      display_name: "University SSO"
      discovery_url: "https://sso.university.edu/.well-known/openid-configuration"
      client_id: ${OIDC_CLIENT_ID}
      client_secret: ${OIDC_CLIENT_SECRET}

user_identity_field: "email" के साथ, जो व्यक्ति Google से और बाद में उसी पते से विश्वविद्यालय के प्रोवाइडर से साइन इन करता है, वह Potato का वही उपयोगकर्ता रहता है और अपने उन्हीं असाइनमेंट पर लौटता है।

पहचान और ऑटो-पंजीकरण

user_identity_field तय करता है कि प्रोवाइडर का कौन सा claim Potato उपयोगकर्तानाम बनेगा। यह email, username, sub या name स्वीकार करता है, और इसका डिफ़ॉल्ट email है। यह मान मायने रखता है क्योंकि एनोटेटर की आउटपुट डायरेक्टरी उपयोगकर्तानाम के नाम पर होती हैं, इसलिए अध्ययन के बीच में इसे बदलने से एनोटेटर अपने पिछले काम से अलग हो जाता है।

auto_register नियंत्रित करता है कि पहला सफल लॉगिन Potato खाता बनाता है या नहीं। इसका डिफ़ॉल्ट true है।

yaml
authentication:
  method: "oauth"
  providers:
    google:
      client_id: ${GOOGLE_CLIENT_ID}
      client_secret: ${GOOGLE_CLIENT_SECRET}
      allowed_domain: "umich.edu"
  user_identity_field: "email"
  auto_register: true

पहुंच नियंत्रण कॉन्फ़िग में पतों की सूची से नहीं, बल्कि प्रोवाइडर के ज़रिए चलता है। कौन साइन इन कर सकता है यह सीमित करने के लिए Google के लिए allowed_domain, GitHub के लिए allowed_org, या अपने OIDC प्रोवाइडर के ग्रुप और ऐप-असाइनमेंट नियंत्रणों का उपयोग करें।

मिश्रित मोड

allow_local_login SSO बटनों के नीचे उपयोगकर्तानाम और पासवर्ड फ़ॉर्म जोड़ता है। इसका डिफ़ॉल्ट false है, इसलिए जब तक आप इसे चालू न करें, SSO स्थानीय लॉगिन की जगह ले लेता है।

yaml
require_password: true
 
user_config:
  allow_all_users: true
 
authentication:
  method: "oauth"
  providers:
    google:
      client_id: ${GOOGLE_CLIENT_ID}
      client_secret: ${GOOGLE_CLIENT_SECRET}
  allow_local_login: true

माइग्रेशन के दौरान दोनों कुछ समय तक साथ चलते हैं। एनोटेटरों को प्रोवाइडर पर ले जाएं, फिर जब सभी प्रोवाइडर के ज़रिए साइन इन कर चुके हों तो allow_local_login हटा दें। मिश्रित मोड उन अध्ययनों के लिए भी है जिनमें संस्थान के एनोटेटरों के साथ ऐसे बाहरी एनोटेटर भी होते हैं जिनका आपके संस्थान में कोई खाता नहीं है।

मिश्रित मोड में स्थानीय खाते वही salted PBKDF2 हैशिंग उपयोग करते हैं जो किसी भी अन्य पासवर्ड खाते में होती है। रीसेट प्रक्रियाओं के लिए पासवर्ड प्रबंधन देखें।

सत्र

सत्र की अवधि एक टॉप-लेवल कुंजी है, दिनों में:

yaml
session_lifetime_days: 7

स्थिर secret_key ही सत्रों को रीस्टार्ट के बाद भी बनाए रखता है।

एडमिन पहुंच

एडमिन एंडपॉइंट OAuth ब्लॉक के बजाय API कुंजी से प्रमाणित होते हैं:

yaml
admin_api_key: ${POTATO_ADMIN_API_KEY}

Potato admin_api_key को पहले कॉन्फ़िग से पढ़ता है, फिर POTATO_ADMIN_API_KEY एनवायरनमेंट वेरिएबल से। यदि दोनों में से कोई सेट नहीं है, तो वह एक कुंजी बनाता है और उसे टास्क डायरेक्टरी में admin_api_key.txt में लिख देता है। कॉल करने वाले इसे X-API-Key हेडर में भेजते हैं।

HTTPS

प्रोडक्शन में OAuth प्रोवाइडर HTTPS रीडायरेक्ट URI मांगते हैं। localhost को छूट है, इसलिए HTTP पर विकास बिना सर्टिफ़िकेट के काम करता है।

रिवर्स प्रॉक्सी के पीछे मूल स्कीम आगे भेजें, अन्यथा Potato जो कॉलबैक URL बनाता है वह http का उपयोग करेगा और प्रोवाइडर उसे अस्वीकार कर देगा:

nginx
location / {
    proxy_pass http://localhost:8000;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
}

कॉन्फ़िगरेशन संदर्भ

कुंजीप्रकारडिफ़ॉल्टविवरण
authentication.methodstringin_memoryin_memory, database, clerk या oauth
authentication.providersdictoauth के लिए आवश्यकहर प्रोवाइडर के लिए एक प्रविष्टि, प्रोवाइडर के नाम से कुंजीकृत
authentication.user_identity_fieldstringemailemail, username, sub या name
authentication.allow_local_loginboolfalseSSO बटनों के साथ पासवर्ड फ़ॉर्म दिखाता है
authentication.auto_registerbooltrueपहले लॉगिन पर Potato खाता बनाता है
secret_keystringरैंडमटॉप-लेवल। स्थायी सत्रों के लिए स्थिर मान आवश्यक
session_lifetime_daysint7टॉप-लेवल सत्र अवधि
admin_api_keystringजनरेट किया गयाएडमिन एंडपॉइंट के लिए टॉप-लेवल कुंजी

प्रति-प्रोवाइडर कुंजियां:

कुंजीप्रकारआवश्यकविवरण
client_idstringहांप्रोवाइडर से
client_secretstringहांप्रोवाइडर से
discovery_urlstringजेनेरिक OIDC के लिएOIDC डिस्कवरी एंडपॉइंट
display_namestringनहींलॉगिन बटन का टेक्स्ट
allowed_domainstringनहींएक ईमेल डोमेन तक सीमित करता है
allowed_orgstringनहींएक GitHub संगठन तक सीमित करता है
scopeslistनहींडिफ़ॉल्ट ["openid", "email", "profile"]

पूर्ण उदाहरण

yaml
annotation_task_name: "Annotation Project"
task_dir: "."
 
authentication:
  method: "oauth"
  providers:
    google:
      client_id: ${GOOGLE_CLIENT_ID}
      client_secret: ${GOOGLE_CLIENT_SECRET}
      allowed_domain: "umich.edu"
  user_identity_field: "email"
  auto_register: true
 
secret_key: ${POTATO_SECRET_KEY}
session_lifetime_days: 7
admin_api_key: ${POTATO_ADMIN_API_KEY}
 
data_files:
  - "data/instances.jsonl"
 
item_properties:
  id_key: id
  text_key: text
 
annotation_schemes:
  - annotation_type: radio
    name: sentiment
    description: "What is the sentiment of this text?"
    labels: [Positive, Neutral, Negative]
 
output_annotation_dir: "output/"
export_annotation_format: "jsonl"

समस्या निवारण

प्रोवाइडर रीडायरेक्ट URI अस्वीकार करता है। प्रोवाइडर के पास रजिस्टर किया गया URI /auth/callback/<provider> से बिल्कुल मेल खाना चाहिए। स्कीम और अंत का कोई भी पथ मिलान का हिस्सा होते हैं, इसलिए जो प्रॉक्सी X-Forwarded-Proto आगे नहीं भेजता, वह http कॉलबैक बनाता है जिसे प्रोवाइडर अस्वीकार कर देता है।

रीस्टार्ट के बाद सभी लॉग आउट हो जाते हैं। secret_key सेट नहीं है, इसलिए Potato ने बूट के समय नई कुंजी बनाई।

GitHub संगठन प्रतिबंध किसी सदस्य को अस्वीकार कर देता है। संगठन में उसकी सदस्यता निजी है। या तो वह इसे सार्वजनिक करे, या आप allowed_org हटाकर पहुंच को किसी और तरीके से नियंत्रित करें।

सत्यापन "providers is required" के साथ विफल होता है। method: "oauth" के लिए providers के अंतर्गत कम से कम एक प्रविष्टि चाहिए। method का मान oauth है, किसी प्रोवाइडर का नाम नहीं।


आगे पढ़ें

कार्यान्वयन विवरण के लिए, स्रोत दस्तावेज़ीकरण देखें।