Autentificare cu codai
auth.codai.ro este un provider OpenID Connect standard. Îl folosești când aplicația ta trebuie să acționeze în numele unui utilizator codai; folosești o cheie API simplă când nu trebuie.
https://auth.codai.ro este provider-ul de identitate al codai — un server OpenID Connect conform standardelor, cu discovery, PKCE, refresh token-uri, RP-initiated logout și back-channel logout. Fiecare cont codai se autentifică prin el (parolă, passkey, magic link sau Google), iar fiecare suprafață first-party — hub, pay, docs, aplicațiile desktop și de telefon — este un relying party al lui.
Pentru tine, ca integrator, face un singur lucru pe care restul OIDC nu îl face: după ce un utilizator se autentifică și își dă consimțământul, GET /connect/key emite o cheie API de gateway legată de acel utilizator și de acel consimțământ, astfel încât aplicația ta poate apela https://ai.codai.ro în numele lui — facturat pe planul lui, revocabil de el, fără să vezi vreodată parola sau celelalte chei ale lui.
Ai nevoie de el?
| Construiești… | Folosești |
|---|---|
| Un server, script, bot sau job CI care apelează codai ca tine | O cheie API simplă din hub.codai.ro → Keys. Fără OIDC. Vezi startul rapid pentru gateway. |
| O aplicație în care fiecare utilizator al tău vine cu propriul cont codai și plătește pentru propriul consum | Conectare cu codai — fluxul de conectare. Un redirect, un schimb de token, un GET /connect/key. |
| O aplicație web care trebuie doar să știe cine este utilizatorul codai (SSO), fără inferență | Fluxul OIDC standard cu code; ceri openid email profile și citești ID token-ul. |
| Un client MCP care trebuie să ajungă la tool-urile și memoria codai | OIDC cu scope-ul mcp pe resursa https://ai.codai.ro/mcp; clienții se pot înregistra singuri prin Dynamic Client Registration. |
| Un CLI fără browser pe aceeași mașină | Grant-ul de device authorization este implementat, dar astăzi e provizionat doar pentru clienții first-party — întreabă-ne. |
Discovery
curl -s https://auth.codai.ro/.well-known/openid-configuration | jq '{issuer, authorization_endpoint, token_endpoint, userinfo_endpoint, jwks_uri, end_session_endpoint, grant_types_supported, code_challenge_methods_supported, token_endpoint_auth_methods_supported, scopes_supported}'| Endpoint | Cale |
|---|---|
| Authorization | GET /auth |
| Token | POST /token — limitat la 60 de cereri/min per IP (429 { "error": "rate_limited" }) |
| UserInfo | GET /me |
| JWKS | GET /jwks — toate cheile RS256 nerevocate; cea mai nouă semnează |
| Introspection / revocation | POST /token/introspection, POST /token/revocation |
| End session | GET /session/end |
| Dynamic registration | POST /reg (doar clienți publici) |
| Device authorization | POST /device/auth |
| Emitere cheie de gateway | GET /connect/key — specific codai, vezi fluxul de conectare |
Lucruri bune de știut înainte să scrii cod:
- PKCE (
S256) este obligatoriu pentru fiecare client, public sau confidențial. Nu există flux implicit sau hibrid;response_typeeste întotdeaunacode. - Metode de autentificare a clientului:
none(public),client_secret_basic,client_secret_post,private_key_jwt.client_secret_jwtnu este oferit. - Tipuri de grant:
authorization_code,refresh_token,urn:ietf:params:oauth:grant-type:device_code. - Durate de viață ale token-urilor: access token 1 h, ID token 1 h, authorization code 10 min, refresh token 30 de zile cu rotație (≤ 1 an în total), grant de consimțământ 90 de zile, sesiune de browser pe IdP 14 zile.
- Refresh token-urile se emit doar când clientul are grant-ul
refresh_tokenși cererea a cerutoffline_access. Clienții publici rotesc întotdeauna la folosire. - Access token-urile pentru resursa implicită (
https://ai.codai.ro/v1) sunt opace — le validezi prin introspection sau le folosești direct la/connect/key. Token-urile pentruhttps://ai.codai.ro/mcpsunt JWT-uri RS256 pe care gateway-ul le verifică local. - Step-up:
acr_valuesacceptăurn:codai:acr:pwd,urn:codai:acr:passkey,urn:codai:acr:mfa; IdP-ul cere din nou autentificarea dacă metoda sesiunii este mai slabă sau mai veche de 10 minute.
Înregistrarea unui client
Nu există încă înregistrare self-service a clienților pentru fluxul de conectare — clienții sunt provizionați de echipa codai. Trimite-ne numele clientului, redirect URI-urile exacte (fără wildcard-uri; http:// doar pe loopback), dacă clientul este public (none) sau confidențial (client_secret_basic, client_secret_post sau private_key_jwt) și scope-urile de care ai nevoie. Primești un client_id și, pentru clienții confidențiali, un secret afișat o singură dată.
Clienții MCP sunt excepția: POST /reg acceptă înregistrări RFC 7591 fără un initial access token, creând un client public (dcr_…) cu 1 – 5 redirect URI-uri https:// / loopback / cu schemă personalizată și grant-ul authorization_code.
Deconectare
- RP-initiated: trimiți browser-ul la
GET /session/end?id_token_hint=<id_token>&post_logout_redirect_uri=<registered>&state=<yours>. Redirect URI-ul trebuie să fie înregistrat exact (fără query string — poartă ținta ta locală înstate). Fărăid_token_hint, IdP-ul afișează întâi o pagină de confirmare. - Back-channel: dacă clientul tău a înregistrat un
backchannel_logout_uri, IdP-ul facePOSTcu unlogout_token(form-encoded, potrivit pesid) când sesiunea utilizatorului se încheie oriunde. Răspunzi200sau204.
Revocarea consimțământului — utilizatorul își deconectează aplicația ta sau un admin revocă grant-ul — revocă și orice cheie de gateway emisă pentru el. Cheia codai_… pe care o stochezi va începe să returneze 401 invalid_api_key; tratează asta ca „cere-i utilizatorului să se conecteze din nou".