Skip to content

Securitate & control de acces

Impuse în stratul de service (nu doar UI), în security/acl/DocumentAccessControl.

NivelCine poate citi
L1 PUBLICoricine, inclusiv neautentificat (portal public)
L2 PERSONALadmin/proprietar/încărcător, membru de scope (organizație/bucket), sau beneficiar al unui grant
L3 SECRETDOAR clearance nivelMaxim = SECRET ȘI un PartajareDocument explicit pe document — nicio cale generală; fiecare acces L3 e auditat; L3 nu e returnat niciodată în liste/căutare/API fără grant

readableSpecification() (filtru de listă/căutare) e ANDat în DocumentQueryService; verificările pe entitate: checkRead (→ 404, nu divulgă existența), checkWrite (→ 403), checkCreate.

  • STANDARD — SHA-256 de integritate la upload.
  • HASH — SHA-256.
  • PAROLA — bcrypt, verificat la download.
  • CRIPTAT — AES-256-GCM la repaus în object-store; decriptat la livrare.
flowchart LR
subgraph Umane
P[user/parolă] --> J[JWT HS512 auto-emis]
K[Keycloak OIDC] --> J
end
subgraph Mașini
CC[client-credentials] --> MT[JWT ROLE_MACHINE + SCOPE_*]
end
J --> RS[Resource server<br/>authorities-claim=auth, prefix gol]
MT --> RS
  • User/parolă: POST /api/authenticate → JWT HS512 (claim auth). DomainUserDetailsService mint și ROLE_SERVICE_ADMIN/ROLE_ORG_ADMIN.
  • Keycloak OIDC (opt-in, profil oidc): /oauth2/authorization/oidc → OidcAppTokenSuccessHandler emite ACELAȘI JWT HS512, predat SPA-ului prin fragment #id_token=….
  • API mașină (/api/v1): POST /api/v1/token (client-credentials, form sau Basic) → JWT cu ROLE_MACHINE + SCOPE_documente.read|write; delimitat pe emitent; L3 niciodată expus pe acest canal.
PatternAcces
POST /api/authenticate, /api/register, /api/activatepermitAll
GET /api/public/**permitAll (L1)
POST /api/v1/tokenpermitAll
/api/v1/**ROLE_MACHINE
/api/admin/**ROLE_ADMIN (service + org admin)
/api/**authenticated
/management/health, /info, /prometheuspermitAll
/management/**, /v3/api-docs/**ROLE_ADMIN

@EnableMethodSecurity(securedEnabled = true) — activ pentru @PreAuthorize.

Partajare (owner-initiated) vs cerere de acces

Section titled “Partajare (owner-initiated) vs cerere de acces”
  • Partajare (POST /api/documents/{id}/partajeaza): proprietarul/scriitorul acordă acces (CITIRE/SCRIERE/CITIRE_SCRIERE) unui Client sau operator. Impus acl.checkWrite. Partajarea unui L3 către un operator cere ca acel operator să aibă clearance SECRET.
  • Cerere de acces (POST /api/documents/cerere): cine NU vede un document îl cere după cod; un admin aprobă (→ creează grant).

EvenimentDocument — UPDATE/DELETE interzise (AppendOnlyAuditGuard + trigger DB). Fiecare tranziție de status scrie un eveniment.

content-security-policy include blob: pentru frame-src/img-src/object-src (previzualizarea inline PDF/imagine). Download-urile encodează Content-Disposition filename UTF-8 (RFC 5987) — altfel diacriticele rup HTTP/2 în Chrome.