14 KiB
didiKeycloak - Index
Deployment LOCAL (activ): Keycloak ruleaza ca un singur container
didi-keycloakpe masina de deployment. Nu exista cluster SSO / Swarm.
- Imagine:
quay.io/keycloak/keycloak:26.0, pornit custart-dev --import-realm.- Port:
28080(host) ->8080(container), servit sub calea relativa/auth(KC_HTTP_RELATIVE_PATH=/auth).KC_HOSTNAME_STRICT=false,KC_PROXY_HEADERS=xforwarded— hostname derivat din headerele proxy-ului din fata.- Doua realm-uri importate din
realm-import/:didi-clients(useri finali) +didi-admins(operatori: admin / moderator / senior_moderator).- Temele custom sunt bind-mount-uite din folderul acesta in
/opt/keycloak/themes/.- Master credentials:
admin/admin123(KEYCLOAK_ADMIN/KEYCLOAK_ADMIN_PASSWORD).
Serviciul de autentificare si autorizare al platformei DIDI. Bazat pe Keycloak, gestioneaza utilizatori, roluri, grupuri, clienti OAuth2 si token-uri JWT. Include teme custom de login si template-uri email in romana.
Imagine: quay.io/keycloak/keycloak:26.0 (container local didi-keycloak)
Container: didi-keycloak (activ, pe masina de deployment)
Port: 28080 (host) -> 8080 (container), sub /auth
Realm-uri: didi-clients (useri) + didi-admins (operatori)
Baza de date: PostgreSQL didi-postgres:5432/DIDI (KC_DB=postgres, user bos_interface)
Ce face
- Autentificare OAuth2/OIDC -- login, logout, refresh token, SSO
- Management utilizatori -- creare, roluri, grupuri, tier-uri
- Emitere token-uri JWT -- access token (10 min), refresh token, SSO session (2h)
- Validare JWT -- Kong valideaza token-urile emise de Keycloak
- Securitate cont -- brute force (lockout dupa 5 incercari esuate), MFA TOTP, password policy
- Deep linking mobil -- redirectare catre app mobila dupa verificare email
- Teme custom -- login page dark purple, emailuri in romana
Structura fisierelor
realm-import/
didi-clients-realm.json -- Configurare completa realm (clienti, roluri, grupuri, utilizatori)
themes/
didi-clients-theme/ -- Tema principala (dark purple)
login/
theme.properties -- Configurare tema login
register.ftl -- Formular inregistrare
login-reset-password.ftl -- Resetare parola
login-verify-email.ftl -- Pagina verificare email
info.ftl -- Routing mobil/web dupa actiuni
register-commons.ftl -- Macro acceptare termeni
messages/
messages_en.properties -- Etichete UI engleza
resources/
css/login.css -- Stil dark purple (784 linii)
js/placeholders.js -- Placeholders formulare
email/
theme.properties -- Configurare tema email
html/
email-verification.ftl -- Template verificare email (romana, dark theme)
executeActions.ftl -- Template actiuni (dark purple gradient)
text/
email-verification.ftl -- Versiune text plain
didi-ai-theme/ -- Tema alternativa (white, blue accents)
login/
theme.properties
resources/
css/login.css
img/logo.png
didi-backend-theme/ -- Tema backend (white, "didi - Backend")
login/
theme.properties
resources/
css/login.css
img/logo.png
Zero cod custom backend. Doar configurare realm JSON + teme FreeMarker/CSS.
Clienti OAuth2 (4)
| Client ID | Tip | Scop | Flow-uri | PKCE |
|---|---|---|---|---|
| didi-web-app | Public | Frontend web utilizatori | Standard + Direct Access | nu |
| admin-dashboard | Public | Dashboard admin React | Standard + Direct Access | S256 |
| orchestrator-api | Confidential | Serviciu backend orchestrator | Direct Access + Service Account | nu |
| kong-api-gateway | Bearer Only | Gateway JWT validation | Service Account only | nu |
didi-web-app
- Redirect URIs: localhost:3001, localhost:5173, localhost:13001, localhost:33001 (+ 127.0.0.1)
- Web Origins: aceleasi + wildcard
- Scopes: web-origins, acr, profile, roles, email
admin-dashboard
- Root URL: http://localhost:13003
- PKCE: S256 (obligatoriu)
- Redirect URIs: localhost:13003, localhost:3003, localhost:33003, localhost:33001, localhost:3001, 127.0.0.1:13003, 127.0.0.1:3003, 127.0.0.1:33003, 127.0.0.1:33001, 10.11.50.11:33003, 10.11.50.11:3003
- Post Logout: localhost:13003, localhost:3003, localhost:33003, 10.11.50.11:33003
orchestrator-api
- Secret: nmmImrmPAcADuPh-ZTqLY7GDhCAjfXsolDOM6TxZbHg
- Service Account: activat
- Bearer Only: implicit (confidential)
kong-api-gateway
- Secret: Fu1rJ8QsjCj4j4_qZiMXyx6Ewo3xC2ik7X5m_MvSLOE
- Bearer Only: da (nu face login, doar valideaza)
- Service Account: activat
Roluri (doua realm-uri)
Operatorii (admin / moderator / senior_moderator) traiesc in realm-ul didi-admins; realm-ul didi-clients contine doar capabilitati de user si tier-uri de abonament.
Realm didi-admins (operatori)
| Rol | Scop |
|---|---|
| admin | Acces complet la platforma + admin dashboard |
| moderator | HIL moderator -- poate revendica si rezolva intrari din coada (admin dashboard /moderation) |
| senior_moderator | Senior HIL moderator -- poate escalada si forta gold atom in brain |
Realm didi-clients (useri finali)
| Rol | Scop |
|---|---|
| viewer | Poate vizualiza rezultate analize |
| analyst | Poate crea si gestiona analize |
| api_user | Poate accesa endpoint-uri API |
| free_tier | Privilegii tier gratuit |
| paid_tier | Privilegii tier platit |
| enterprise_tier | Privilegii tier enterprise |
Roluri implicite la inregistrare (didi-clients): viewer + free_tier
Grupuri (6)
| Grup | Roluri | Tier | Limita zilnica | Rate limit |
|---|---|---|---|---|
| free-users | free_tier, viewer, api_user | free | 10 | 10/min |
| paid-users | paid_tier, viewer, analyst, api_user | paid | 100 | 60/min |
| enterprise-users | enterprise_tier, viewer, analyst, api_user | enterprise | nelimitat | 600/min |
| administrators | admin, analyst, viewer, api_user, enterprise_tier | admin | nelimitat | nelimitat |
| Grup | Roluri | Scop |
|---|---|---|
| moderators-team | moderator | HIL review staff |
| senior-moderators-team | moderator + senior_moderator | Lead moderators with brain gold-promotion authority |
Atributele de grup (tier, daily_limit, rate_limit) sunt disponibile in token-ul JWT si pot fi folosite de Kong/backend pentru rate limiting.
Acces admin dashboard
| Pagina admin dashboard | viewer / paid_tier / etc | moderator | senior_moderator | admin |
|---|---|---|---|---|
| /admin/* (any) | 403 (Unauthorized page -> public app) | Dashboard + History + Moderation | same + force_gold_brain | tot |
| /users, /framework, /llm-components, /providers | nu | nu | nu | da |
| /history | nu | da | da | da |
| /moderation/* | nu | da | da | da |
Note: viewer este rolul implicit asignat la toate signup-urile (defaultRoles: [viewer, free_tier]). End-userii (clientii) primesc acest rol; ei NU vad niciodata admin dashboard.
Utilizatori pre-configurati (5)
| Parola | Grup | Rol principal | |
|---|---|---|---|
| admin@didi.local | admin123 | administrators | admin |
| demo@didi.local | Demo123! | free-users | viewer |
| free@didi.local | password123 | free-users | free_tier |
| paid@didi.local | password123 | paid-users | paid_tier |
| enterprise@didi.local | password123 | enterprise-users | enterprise_tier |
Toti au emailVerified: true. Parolele nu sunt temporare.
Setari token
| Parametru | Valoare |
|---|---|
| Access Token Lifespan | 600s (10 minute) |
| Access Token Implicit | 900s (15 minute) |
| SSO Session Idle | 7200s (2 ore) |
| SSO Session Max | 86400s (24 ore) |
| Algoritm semnatura | RS256 |
Securitate
Aplicata pe ambele realm-uri (didi-clients + didi-admins).
Brute force protection
- Activat (
bruteForceProtected: true) - Max incercari esuate: 5 (
failureFactor) - Timp asteptare: 60s (increment) / min quick-login wait 60s / quick-login check 1000ms
- Max wait: 900s (15 minute)
- Fereastra glisanta: 43200s (12 ore)
- Lockout permanent: dezactivat
MFA / TOTP (livrabil Lot 2)
- Politica OTP:
otpPolicyType=totp(HmacSHA1, 6 cifre, perioada 30s) — pe ambele realm-uri. - Required action
CONFIGURE_TOTPenabled pe realm-uldidi-admins(operatorii sunt fortati sa configureze TOTP; userii noi de admin primescCONFIGURE_TOTPinrequiredActionsla prima logare, alaturi deUPDATE_PASSWORD). - Realm-ul
didi-clientsare politica TOTP configurata (MFA disponibil pentru enrolment).
Password policy (ambele realm-uri)
length(10) and digits(1) and upperCase(1) and lowerCase(1) and notUsername and passwordHistory(3)
Minim 10 caractere, cel putin o cifra, o majuscula, o minuscula, parola != username, fara reutilizarea ultimelor 3 parole.
Setari realm
- Inregistrare: dezactivata (registrationAllowed: false)
- Login cu email: da
- Email ca username: da
- Verificare email: dezactivata (verifyEmail: false)
- Editare username: nu
- Emailuri duplicate: nu
- Remember me: da
- Reset parola: da
Teme
didi-clients-theme (principala, dark purple)
- Background: #050510 (foarte inchis)
- Accent: #A855F7 -> #7C3AED -> #6D28D9 (gradient purple)
- Card: glassmorphism (backdrop blur, border semi-transparent)
- Logo: "didi" (48px, font Outfit)
- Subtitle: "Misinformation Detection Platform"
- Font: Outfit (display) + Inter (body)
- Butoane: gradient purple cu glow la hover
- Responsive: suporta mobile (100dvh)
didi-ai-theme (alternativa)
- Background: alb
- Accent: #0052CC (albastru)
- Subtitle: "didi - AI Platform"
didi-backend-theme (alternativa)
- Background: alb
- Accent: #0052CC (albastru)
- Subtitle: "didi - Backend"
Template-uri email
email-verification.ftl
- Limba: romana
- Titlu: "Verifica adresa de email"
- Stil: dark purple gradient header
- URL custom: https://didi365.eu/api/auth/verify-email?key=...
- Afiseaza timpul de expirare (convertit din secunde)
- Deep link mobil: didi://email-verified, com.didi365.app://email-verified
executeActions.ftl
- Stil: dark purple gradient
- Suporta actiuni multiple
- Deep linking mobil
info.ftl (routing dupa actiuni)
- Detecteaza client ID (didi-mobile-app vs didi-web-app)
- Mobile: deep link cu fallback dupa 1.5-3s
- Web: redirect la /email-verified dupa 2s
- Butoane: "Deschide in aplicatie" / "Continua in browser"
Fluxul de autentificare
Utilizator deschide aplicatia
|
v
Redirect la Keycloak login (tema didi-clients-theme)
|
v
Utilizatorul introduce email + parola
|
v
Keycloak valideaza + emite JWT (access token 10 min, refresh token)
|
v
Redirect inapoi la aplicatie cu authorization code
|
v
Aplicatia schimba codul in token-uri (PKCE pentru admin-dashboard)
|
v
Requesturi API cu Authorization: Bearer {access_token}
|
v
Kong valideaza JWT-ul (plugin jwt, consumer didi-keycloak-users, RS256, match pe iss)
|
v
Backend-ul decodeaza JWT pentru user_id/email (fara re-validare)
|
v
La fiecare 30s, aplicatia face refresh token daca expira in < 70s
Cum comunica cu restul platformei
| Cine | Ce face | Cum |
|---|---|---|
| admin-dashboard | Login/logout utilizator | OAuth2 Standard Flow + PKCE |
| didi-web-app (frontend) | Login/logout utilizator | OAuth2 Standard Flow |
| Kong | Valideaza JWT pe fiecare request (RS256, match pe iss) | plugin jwt + consumer didi-keycloak-users |
| didiFramework (auth.ts) | Auto-inregistrare utilizator, Keycloak Admin API | Direct Access + Admin credentials |
| didiFramework (admin.ts) | Lista utilizatori, update emailVerified | Keycloak Admin API |
| agent-v3 | Decodeaza JWT din header (sub, email) | Doar decodare, fara validare (Kong a validat deja) |
Admin API folosit de automatizari
- Admin API base:
http://localhost:28080/auth/admin/realms/{didi-clients|didi-admins}/(Keycloak local, sub/auth) - Master token via
POST /auth/realms/master/protocol/openid-connect/tokencuclient_id=admin-cli, username=admin, password=admin123 - Folosit de fluxul de auto-inregistrare didiFramework + scripturi viitoare de automatizare.
Roluri JWT in token-urile clientilor
Token-ul JWT contine acum array-ul realm_access.roles, parsat de agent-v3 (req.jwtRoles) pentru verificarile de rol pe endpoint-urile de moderare. Token-ul se reimprospateaza automat la fiecare 30s (comportament existent).
Baza de date
Keycloak foloseste PostgreSQL local, aceeasi instanta ca restul platformei:
KC_DB=postgresKC_DB_URL=jdbc:postgresql://didi-postgres:5432/DIDI(schemapublic)- User:
bos_interface - Schema proprie Keycloak (gestionata automat)
Datele stocate: realm config, utilizatori, sesiuni, events, client sessions.
Audit si evenimente
- Evenimente utilizator: activate (jboss-logging)
- Evenimente admin: activate cu detalii
- Logare: in stdout Docker (accesibil prin docker logs)
Recent Changes
- MFA / TOTP (livrabil Lot 2):
otpPolicyType=totppe ambele realm-uri; required actionCONFIGURE_TOTPenabled pedidi-admins(operatorii sunt fortati sa configureze TOTP la prima logare, alaturi deUPDATE_PASSWORD). - Password policy pe ambele realm-uri:
length(10) and digits(1) and upperCase(1) and lowerCase(1) and notUsername and passwordHistory(3). - Realm
didi-admins(operatori): 3 roluriadmin/moderator/senior_moderator; clienti publiciadmin-dashboard+ai-platform-dashboard; useri de testmoderator.test@didi.local,senior.moderator.test@didi.local. - Realm
didi-clients(useri finali): capabilitativiewer,analyst,api_user+ tier-urifree_tier,paid_tier,enterprise_tier; clientididi-web-app,admin-dashboard,orchestrator-api,kong-api-gateway. - Deployment local: container unic
didi-keycloak(quay.io/keycloak/keycloak:26.0,start-dev --import-realm), port28080sub/auth,KC_HOSTNAME_STRICT=false,KC_PROXY_HEADERS=xforwarded, DBdidi-postgres:5432/DIDI. Fara cluster SSO / Swarm / Infinispan.