Toegangsbeleid
Versie 1.0.0 - maart 2026
Dit document beschrijft het toegangsbeleid van Remedice, conform NEN 7510 (A.9 - Toegangsbeheer).
1. Authenticatie-architectuur
Remedice hanteert een gelaagd authenticatiemodel:
1.1 Primaire authenticatie
- E-mailadres + wachtwoord als eerste factor
- Wachtwoordbeleid: minimaal 10 tekens, niet in veelgebruikte-wachtwoordenlijst, niet geheel numeriek, verplicht minstens 1 cijfer en 1 speciaal teken, gecontroleerd tegen bekende datalekken (Have I Been Pwned)
- Wachtwoorden worden gehashd opgeslagen (PBKDF2-SHA256 met unieke salt)
1.2 Tweede factor (verplicht)
- TOTP (Time-based One-Time Password) via authenticator-app (Google Authenticator, Authy, etc.)
- 6-cijferige code met 30-seconden venster
- Verplicht voor alle gebruikers - geen uitzonderingen
- Bij eerste login: QR-code + geheime sleutel voor handmatige invoer
1.3 Biometrische login (optioneel)
- Na succesvolle TOTP-setup kan de gebruiker biometrische login activeren (Touch ID / Face ID)
- Gebaseerd op trusted device-registratie
- Uniek per device per gebruiker
1.3bis Optionele identiteitskoppeling (ZORG-ID, Google, Apple)
- ZORG-ID, Google en Apple zijn optionele OIDC-koppelingen (
UserOidcIdentity); ze vervangen de verplichte wachtwoord- en TOTP-basislogin niet. - Een gekoppelde provider kan als alternatieve sterke inlogroute dienen, maar is nooit een tweede factor.
- Toegang tot patientdata wordt niet met een ZORG-ID- of UZI-binding afgedwongen, maar met RBAC plus step-up (zie 2.3 en 6).
1.4 Sessies
- JWT-tokens: Access token (30 min), Refresh token (12 uur glijdend, met een absolute maximumduur van 7 dagen)
- Token-rotatie bij verversing (oude refresh token wordt geblacklist)
- Verlopen tokens worden dagelijks opgeschoond via een nachtelijke Celery-taak (
flush_expired_jwt_tokens)
Token-opslag per platform:
| Platform | Opslag | Toelichting |
|---|---|---|
| Web | HttpOnly cookies | Tokens zijn nooit toegankelijk via JavaScript; beschermt tegen XSS. localStorage en sessionStorage worden expliciet vrijgehouden van tokens. |
| iOS / Android | expo-secure-store (Keychain / Keystore) | OS-niveau versleuteling; niet toegankelijk voor andere apps. |
Op het webplatform worden sessie-gerelateerde niet-gevoelige gegevens (gebruikersinfo, tenant, permissies) wel in localStorage opgeslagen om herlaadprestaties te verbeteren. Deze gegevens bevatten geen authenticatietokens en worden overschreven bij elke succesvolle sessieverificatie.
2. Autorisatie (RBAC)
2.1 Model
Remedice gebruikt een role-based access control (RBAC) model:
- Rollen worden per tenant (apotheek) gedefinieerd
- Elke rol bevat een set permissies (permissiecodes)
- Gebruikers worden aan rollen gekoppeld
- Permissies worden afgedwongen via
HasPermissionCode(backend) enuseHasPermission/PermissionGate(frontend)
2.2 Permissiecategorieen
Permissies zijn georganiseerd per module:
review.*- Medicatiebeoordeling (view, edit, manage_settings)atlas.*- Atlas Chatsettings.*- Instellingen (manage_users, manage_roles, etc.)roster.*- Roosterplanning (publish, manage_settings)portal.*- Algemene portaalfuncties
2.3 Least privilege
- Gebruikers krijgen alleen de permissies die nodig zijn voor hun functie
- UI-elementen worden verborgen voor gebruikers zonder de vereiste permissie (permission gating)
- Backend-endpoints retourneren 403 Forbidden bij onvoldoende rechten
- Autorisatieweigeringen worden gelogd als HIGH-severity event
- Patientdata-endpoints vereisen naast de RBAC-permissie ook step-up: een verse tweede factor (TOTP of biometrie) binnen een venster van 30 minuten (
RequiresFreshStepUp)
3. Account lifecycle
3.1 Aanmaken
- Nieuwe accounts worden aangemaakt via het uitnodigingssysteem
- Een beheerder stuurt een uitnodiging per e-mail (geldig 7 dagen, SHA256-gehasht token)
- Bij acceptatie stelt de gebruiker wachtwoord in en configureert TOTP
3.2 Wijzigen
- Gebruikersgegevens (naam, e-mail, telefoon) wijzigbaar door de gebruiker zelf of een beheerder
- E-mailwijzigingen worden gelogd als HIGH-severity event
- Rolwijzigingen alleen door gebruikers met
settings.manage_userspermissie
3.3 Deactiveren
- Soft delete: e-mailadres wordt vervangen door sentinel-waarde met UUID,
deleted_atwordt gezet - Account is niet meer bruikbaar voor login
- Gegevens blijven bewaard conform bewaartermijnen
- Heractivatie mogelijk door beheerder (binnen 30 dagen)
3.4 Definitieve verwijdering
- Na 30 dagen soft delete of op expliciet verzoek conform AVG (recht op vergetelheid)
- Permanente verwijdering van persoonsgegevens, tenzij wettelijke bewaarplicht geldt
4. Trusted devices
- Gebruikers kunnen apparaten registreren als "trusted" voor biometrische login
- Registratie vereist een devicefingerprint + secret hash
- Maximaal 1 registratie per device per gebruiker
- Beheerder kan trusted devices intrekken
- Rate limiting op device-registratie: 5/min
5. Rate limiting
| Endpoint | Limiet |
|---|---|
| Login | 10/min |
| TOTP-verificatie | 5/min |
| WebLogin start | 10/min |
| WebLogin status | 120/min |
| WebLogin bevestiging | 30/min |
| Device-registratie | 5/min |
| Wachtwoord wijzigen | 10/min |
| TOTP-reset | 10/min |
| Sessiebeheer | 30-60/min |
Naast rate limiting geldt een brute-force-lockout: na 5 mislukte loginpogingen wordt het account 15 minuten vergrendeld.
6. ZORG-ID en externe zorgverleners
- Externe zorgverleners krijgen een gewoon tenant-account met een RBAC-rol via dezelfde uitnodigingsflow als interne medewerkers. Er is geen apart artsen-portaal en geen aparte permissiestructuur.
- ZORG-ID (OIDC) is een optionele identiteitskoppeling, naast Google en Apple, vastgelegd in
UserOidcIdentity. - Toegang tot patientdata wordt afgedwongen met RBAC en step-up-authenticatie, niet met een ZORG-ID-binding. Een actie op patientdata vereist een verse tweede factor binnen een venster van 30 minuten (
RequiresFreshStepUp).
7. Admin-toegang
- Het Django-adminpaneel hangt op een niet-raadbaar pad (
ADMIN_URL) in plaats van het standaard/admin/ - Toegang vereist een account met de bijbehorende rechten plus verplichte TOTP; er is geen IP-allowlist
- Admin-acties worden gelogd