didi-lot2-backend/backend/services/gateway-auth-layer/didiKeycloak/INDEX.md
2026-07-10 03:39:53 -07:00

14 KiB

didiKeycloak - Index

Deployment LOCAL (activ): Keycloak ruleaza ca un singur container didi-keycloak pe masina de deployment. Nu exista cluster SSO / Swarm.

  • Imagine: quay.io/keycloak/keycloak:26.0, pornit cu start-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

  1. Autentificare OAuth2/OIDC -- login, logout, refresh token, SSO
  2. Management utilizatori -- creare, roluri, grupuri, tier-uri
  3. Emitere token-uri JWT -- access token (10 min), refresh token, SSO session (2h)
  4. Validare JWT -- Kong valideaza token-urile emise de Keycloak
  5. Securitate cont -- brute force (lockout dupa 5 incercari esuate), MFA TOTP, password policy
  6. Deep linking mobil -- redirectare catre app mobila dupa verificare email
  7. 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)

Email 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_TOTP enabled pe realm-ul didi-admins (operatorii sunt fortati sa configureze TOTP; userii noi de admin primesc CONFIGURE_TOTP in requiredActions la prima logare, alaturi de UPDATE_PASSWORD).
  • Realm-ul didi-clients are 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/token cu client_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=postgres
  • KC_DB_URL=jdbc:postgresql://didi-postgres:5432/DIDI (schema public)
  • 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=totp pe ambele realm-uri; required action CONFIGURE_TOTP enabled pe didi-admins (operatorii sunt fortati sa configureze TOTP la prima logare, alaturi de UPDATE_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 roluri admin / moderator / senior_moderator; clienti publici admin-dashboard + ai-platform-dashboard; useri de test moderator.test@didi.local, senior.moderator.test@didi.local.
  • Realm didi-clients (useri finali): capabilitati viewer, analyst, api_user + tier-uri free_tier, paid_tier, enterprise_tier; clienti didi-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), port 28080 sub /auth, KC_HOSTNAME_STRICT=false, KC_PROXY_HEADERS=xforwarded, DB didi-postgres:5432/DIDI. Fara cluster SSO / Swarm / Infinispan.