TeamManager kan rollen/leden niet beheren + self-service privilege-escalatie via role-veld (follow-up #22) #27

Closed
opened 2026-07-12 18:54:44 +00:00 by rve · 0 comments
Owner

Context (follow-up van #22)

TeamManager laat admins rollen wijzigen en leden verwijderen, maar de huidige rules op team_members staan dat niet toe:

  • updateRule: '@request.auth.id = id' — alleen self-update; db.updateTeamMember(anderId, {role}) faalt
  • deleteRule: null — alleen superusers; db.deleteTeamMember(id) faalt

Het beheerscherm is daarmee functieloos voor app-admins.

Daarnaast: twee verweven problemen

  1. Privilege-escalatie (security): de huidige self-update-rule beperkt niet wélke velden — elke ingelogde gebruiker kan nu zijn eigen role naar "admin" patchen via de REST-API. De login-resync corrigeert dat pas bij de eerstvolgende login; tot die tijd heeft de gebruiker admin-toegang in de app. Moet dicht in dezelfde wijziging (anders wordt het door de nieuwe admin-rules pas écht gevaarlijk).
  2. Rol-resync-conflict: de hook zet bij elke login de rol terug op basis van ENTRA_ADMIN_EMAILS (ADR-004). Elke UI-promotie zou dus bij de volgende login worden teruggedraaid — beheer via TeamManager blijft schijn zolang de resync ook demoteert.

Fix

  1. Rules (migratie 1781000003 + basis-migratie + setup-script-mirror):
    • updateRule: '(@request.auth.id = id && @request.body.role:isset = false) || @request.auth.role = "admin"' — self-update mag (onboarding raakt role niet), maar het role-veld alleen door admins; dicht meteen de escalatie.
    • deleteRule: '@request.auth.role = "admin"'
  2. Resync wordt escalate-only (pb_hooks/team_members.pb.js): de allow-list garandeert admin-rechten (promotie bij login blijft werken), maar demoteert niet meer — UI-promoties blijven staan. Demotie loopt via TeamManager; allow-list-leden zijn niet via de UI te demoteren (allow-list wint bij volgende login). ADR-004 wordt hierop aangepast.
  3. UI-toelichting in TeamManager bijgewerkt op het nieuwe gedrag.

Verificatie (mock-OIDC matrix)

  • User kan eigen role NIET wijzigen (escalatie dicht), wél eigen onboarding-velden
  • User kan andermans record niet wijzigen/verwijderen
  • Admin kan promoveren, demoteren en verwijderen
  • UI-promotie overleeft de volgende login van het lid (escalate-only)
  • Allow-list-lid blijft admin na login
  • Regressie: #22-matrix, #24-matrix, #18-harness, npm test
## Context (follow-up van #22) TeamManager laat admins rollen wijzigen en leden verwijderen, maar de huidige rules op `team_members` staan dat niet toe: - `updateRule: '@request.auth.id = id'` — alleen self-update; `db.updateTeamMember(anderId, {role})` faalt - `deleteRule: null` — alleen superusers; `db.deleteTeamMember(id)` faalt Het beheerscherm is daarmee functieloos voor app-admins. ## Daarnaast: twee verweven problemen 1. **Privilege-escalatie (security):** de huidige self-update-rule beperkt niet wélke velden — elke ingelogde gebruiker kan nu zijn eigen `role` naar `"admin"` patchen via de REST-API. De login-resync corrigeert dat pas bij de eerstvolgende login; tot die tijd heeft de gebruiker admin-toegang in de app. Moet dicht in dezelfde wijziging (anders wordt het door de nieuwe admin-rules pas écht gevaarlijk). 2. **Rol-resync-conflict:** de hook zet bij elke login de rol terug op basis van `ENTRA_ADMIN_EMAILS` (ADR-004). Elke UI-promotie zou dus bij de volgende login worden teruggedraaid — beheer via TeamManager blijft schijn zolang de resync ook demoteert. ## Fix 1. **Rules** (migratie `1781000003` + basis-migratie + setup-script-mirror): - `updateRule: '(@request.auth.id = id && @request.body.role:isset = false) || @request.auth.role = "admin"'` — self-update mag (onboarding raakt `role` niet), maar het `role`-veld alleen door admins; dicht meteen de escalatie. - `deleteRule: '@request.auth.role = "admin"'` 2. **Resync wordt escalate-only** (`pb_hooks/team_members.pb.js`): de allow-list garandeert admin-rechten (promotie bij login blijft werken), maar demoteert niet meer — UI-promoties blijven staan. Demotie loopt via TeamManager; allow-list-leden zijn niet via de UI te demoteren (allow-list wint bij volgende login). ADR-004 wordt hierop aangepast. 3. UI-toelichting in TeamManager bijgewerkt op het nieuwe gedrag. ## Verificatie (mock-OIDC matrix) - [ ] User kan eigen `role` NIET wijzigen (escalatie dicht), wél eigen onboarding-velden - [ ] User kan andermans record niet wijzigen/verwijderen - [ ] Admin kan promoveren, demoteren en verwijderen - [ ] UI-promotie overleeft de volgende login van het lid (escalate-only) - [ ] Allow-list-lid blijft admin na login - [ ] Regressie: #22-matrix, #24-matrix, #18-harness, npm test
rve closed this issue 2026-07-12 19:04:44 +00:00
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: rve/learning-platform#27