| Sprint | 28 aug – 3 sep 2026 | |
| Epic | OR-3114 | PJ758 — Rollen en rechten |
| Team | Koen · Egon · Yusuf (halftijds) · Jan (halftijds) |
| Ticket | Titel | Status |
|---|---|---|
| OR-3296 | Als frontend wil ik via /v1/me kunnen zien of ik organisaties mag aanmaken | In Test |
| OR-3398 | Permissietests voor Sleutels | In Progress |
30+ commits deze sprint op OR-3296/OR-3398. Details op de volgende slides.
Actie: dit is geen permissie-bug maar een datavalidatie-bug in het command-/domeinlaag — orthogonaal aan dit werk maar ontdekt tijdens het testen ervan. Er moet een nieuw bug-ticket op Jira komen zodat dit niet stil in de sprint-marge verdwijnt.
Permission-model: elke rol krijgt expliciet toegewezen rechten.IRestriction-algebra (AllowList, NotAllowList, CompositeAnd, RequireUnderVlimpersManagement, ...), elk apart unit-getest.Gebruiker logt in → Laag 1 — Controller-poort: heeft deze rol de permissie? → Laag 2 — Policy-restrictie: geldt de permissie ook voor déze organisatie/dit record? → Actie toegestaan of 403
Voorbeeld: een VlimpersBeheerder heeft CanManageKeys — maar enkel als restrictie: enkel als de organisatie onder Vlimpers-beheer staat, en enkel voor toegelaten sleuteltypes. Beide lagen moeten "ja" zeggen.
RolePermissionMap & ScopePermissionMapPermission-enumOnbekende rol of scope → PermissionSet.Empty, fail-closed. Nooit toevallig toegang door een ontbrekende regel.
RolePermissionMap: elke rol expliciet, niets impliciet
public static class RolePermissionMap
{
private static readonly IReadOnlyDictionary<Role, PermissionSet> Map =
new Dictionary<Role, PermissionSet>
{
[Role.AlgemeenBeheerder] = PermissionSet.Of(
Permission.CanManageChildren,
Permission.CanManageContacts,
Permission.CanManageFunctions,
Permission.CanManageCapacities,
Permission.CanManageKeys,
Permission.CanManageBodies,
Permission.CanImport,
Permission.CanReadConfiguration),
[Role.VlimpersBeheerder] = PermissionSet.Of(
Permission.CanManageChildren,
Permission.CanManageLabels,
Permission.CanEditOrganisationLabels),
[Role.AutomatedTask] = PermissionSet.Of(
Permission.CanRunScheduledJobs),
};
Permission.CanManageKeys toegevoegd aan het permissie-enum en aan RolePermissionMapKeyContext + KeyRestrictions: restrictie-context met Vlimpers-status en keytype-allowlistKeyPolicy herbouwd op de IRestriction-algebra i.p.v. hardcoded rol-checksOrganisationKeyController, OrganisationKeyCommandController) gebruiken OrganisationRegistryAuthorize met de nieuwe permissieKeyPolicyCanSelect/CanEdit velden toegevoegd aan de sleutel-list responsOrganisationRegistryAuthorize-attribuut + 5 met het oudere [Authorize(..., Policy=...)] uit de legacy Edit-APIKeyPolicy, LabelPolicy, CapacityPolicy, RegulationPolicy, OrganisationClassificationTypePolicy) — de restrictie op de write-kant zit in de command handler, niet in de command-controllerWél afgedekt: 49 command-controllers (mutaties) + 22 niet-command controllers op het nieuwe attribuut (bv. KboController, VlimpersController, SecurityController, ImportOrganisationsController) + 5 legacy Edit-API-controllers (bv. OrganisationBankAccountController, OrganisationContactsController) op het oudere schema.
Poort wél, restrictie nog niet: de overige 69 van de 76 checken enkel of de rol/permissie aanwezig is (laag 1) — een per-record restrictie (laag 2) is enkel al toegepast bij Sleutels, Labels, Capaciteiten, Regelgeving en OrganisatieClassificaties.
Nog niet afgedekt (66 controllers): de read-only query/list/report-controllers (bv. OrganisationListController, BodyListController, de Report-controllers, SearchController) — deze muteren niets.
Alles hiervan is deze sprint gerealiseerd. Vóór deze sprint (op main): 0 permission-based checks — het Permission-enum, RolePermissionMap, ScopePermissionMap, alle restricties en RequiresPermission bestonden nog niet. KeyPolicy en FormalFrameworkPolicy bestonden wél al, maar checkten intern op rollen — ze zijn deze sprint omgebouwd naar het permissiemodel. Daarnaast: 57 nieuwe PermissionMatrix-integratietests, ~11.700 regels toegevoegd over 212 bestanden.
Permission + IRestriction) — direct via RequiresPermission(...) of via KeyPolicy/FormalFrameworkPolicy: Capaciteiten (3), Toepassingsgebieden (5), Functietypes (2), Locaties (2), Sleutels (2)Geteld per Handle(ICommandEnvelope<...>)-methode (= per command), over 101 handler-bestanden — bestanden als CapacityCommandHandlers bevatten meerdere commands. Let op: veel van die 100 zitten al in een eigen Policy-klasse (bv. LabelPolicy, VlimpersPolicy, CapacityPolicy) — maar die checken vandaag nog rechtstreeks op Role (user.IsInAnyOf(...)), niet op Permission. De "Policy"-naam is dus geen garantie dat het al het nieuwe model is.
Nog geen enkele check in de handler (16 commands): o.a. AssignBodyNumber, UpdateMainLocation, UpdateMainBuilding, CreateOrganisationsFromImport, RebuildProjection, en de 4 KBO-commands (die zijn wel afgeschermd op controller-niveau via OrganisationKboCommandController).
Permission-enum + eerste versie van RolePermissionMap/ScopePermissionMap.CanEditAll verwijderd, eerste controller-gates.CanSelect/CanEdit op keys, restrictions op meerdere contexten, permissietests voor keys, handover- en cookbook-documentatie.Infrastructuur: fout wachtwoord in de AWS/OpenSearch-configuratie tijdens de sprint, ondertussen opgelost.
Deze tijdlijn is gebaseerd op de commit-historie, niet op tasks.md.
| Onderdeel | Status | Nog te doen |
|---|---|---|
| Sleutels (Keys) | Klaar | Dient als referentiepatroon |
| Overige 10 policies (Vlimpers, Label, Capacity, Body, Regulation, ...) | Oud patroon | Nog hardcoded rol-checks, niet omgezet naar IRestriction |
| /v1/me — globale rechten endpoint | In test | OR-3296 |
| Per-veld rechten teruggeven aan frontend | Nog te doen | Niet ingepland |
| AGO-validatiebug (lege velden in events) | Nieuw op te lossen | Nieuw Jira bug-ticket nodig |
RequiresPermissionEén actiepunt: AGO-validatiebug krijgt een eigen Jira-ticket.
| Epic | OR-3114 |