Skip to content

Keycloak Realm Configuration

The ronl realm is defined in config/keycloak/ronl-realm.json. A Keycloak imports it when it starts with --import-realm and has no ronl realm yet: a fresh local Keycloak, or a new environment. An existing realm is not re-imported. ACC and PROD keep their own realms and are changed through scripts, not by importing the file again β€” see Changing the realm.


Realm settings

Setting Value
Realm name ronl
Display name RONL - Regels Overheid Nederland
SSL required External requests only
Registration Disabled
Brute force protection Enabled
Max failed attempts 5
Wait increment 60 seconds
Max delta time 12 hours

Token lifespans

Token Lifespan
Access token 15 minutes (accessTokenLifespan: 900)
Access token (implicit flow) 15 minutes
SSO session idle 30 minutes (ssoSessionIdleTimeout: 1800)
SSO session max 10 hours (ssoSessionMaxLifespan: 36000)
Offline session idle 30 days
Auth code 60 seconds

Client: ronl-business-api

Setting Value
Client ID ronl-business-api
Client authentication Off (public client)
Standard flow Enabled
Implicit flow Disabled
Direct access grants Enabled
Service accounts Disabled
PKCE Not set in the export (no pkce.code.challenge.method attribute)
Valid redirect URIs * (restrict in production)
Web origins * (restrict in production)

Protocol mappers

The following protocol mappers are configured on the ronl-business-api-dedicated client scope:

Mapper name Type Token claim Source attribute
municipality User Attribute municipality municipality
organisation_type User Attribute organisation_type organisation_type
assurance_level User Attribute loa assurance_level
mandate User Attribute mandate mandate
realm_roles User Realm Role realm_access.roles Realm roles
audience-mapper Audience aud Fixed: ronl-business-api
employee_id User Attribute employeeId employee_id
preferred_username User Property preferred_username username
email User Property email email
given_name User Property given_name firstName
family_name User Property family_name lastName

All mappers except audience-mapper have id.token.claim, access.token.claim, and userinfo.token.claim set to true; audience-mapper adds the audience to the access token only. The employeeId claim is present only for users who have the employee_id attribute set (caseworkers and HR staff). It is used by the dashboard to auto-fetch onboarding data on login without requiring a manual ID input.

email, given_name and family_name identify the signer for ValidSign: without an email claim the backend refuses to create a signing package. ACC and PROD receive these three with scripts/keycloak-add-token-claim-mappers.sh.


Machine-to-machine clients

Three confidential clients authenticate with a service account and no user:

Client ID Name Description
operaton-mcp-client Operaton MCP Client Machine-to-machine client for MCP-based Operaton interaction via the RONL Business API
edocs-mcp-client eDOCS MCP Client Used by the AI Assistant's eDOCS MCP subprocess to call this backend's own /v1/edocs/* HTTP surface
copilot-studio-edocs Copilot Studio β€” eDOCS Machine-to-machine client for Microsoft Copilot Studio eDOCS POC

Identity provider: entra-flevoland

An OIDC provider for Provincie Flevoland's Entra ID, configured by scripts/keycloak-add-entra-idp.sh rather than by the realm export, because it carries a client secret. Its mappers set municipality = flevoland, organisation_type = province and assurance_level = substantieel, and map the Entra app roles IOU_ADMIN, IOU_USERS, IOU_PA and IOU_INFRA to admin, caseworker, public-affairs and infra-projectteam, on every login. The provider is hidden on the Keycloak login form (hideOnLogin); Flevoland employees reach it through the landing page. It stores the Entra tokens it receives (storeToken, with offline_access in its default scope), so the backend can act in eDOCS as the person; the same script adds the broker client's read-token role to default-roles-ronl and the broker-roles client mapper to ronl-business-api. None of this is in the realm export. See Entra ID.

The export itself carries two SAML providers, digid (DigiD) and eidas (eIDAS), both disabled.


Realm roles

The realm defines 60 roles.

General

Role Description
citizen Regular citizen using municipality services
representative Representative acting on behalf of a citizen (with mandate)
caseworker Municipality caseworker processing applications
admin Municipality administrator
hr-medewerker HR department employee who manages staff onboarding
infra-projectteam Infrastructure project team member β€” can claim RIP Phase 1 tasks
infra-medewerker Infrastructure employee role assigned via HR onboarding DMN

Management capacity claim

Role Description
manager Line manager β€” can start a management capacity claim and prepare intake/staffing/hiring forms
board-secretary Board Secretary β€” schedules capacity claims on the Board of Directors agenda
board-director Board of Directors member β€” decides approval/rejection of capacity claims
hrm-unit HRM unit β€” handles recruitment handover for approved staffing claims
procurement-unit Procurement unit β€” handles procurement handover for approved hiring claims
planning-control-officer Planning & Control officer β€” co-recipient of procurement handover
financial-controller Financial controller β€” registers the financial reservation for approved claims
hr-business-partner HR Business Partner β€” participates in the reconsideration meeting on rejected claims
personnel-controller Personnel Controller β€” participates in the reconsideration meeting on rejected claims

Besluitvorming onder gedelegeerde bevoegdheid

One role per human lane of the process; see Caseworker β€” Besluitvorming.

Role Description
besluit-indiener Besluitvorming gedelegeerde bevoegdheid β€” Aanvrager / Indiener: bereidt het besluit voor en dient het in
besluit-jurist Besluitvorming gedelegeerde bevoegdheid β€” Juridische Zaken / Compliance: toetst en adviseert
besluit-bestuursautoriteit Besluitvorming gedelegeerde bevoegdheid β€” Bevoegde bestuursautoriteit: neemt geΓ«scaleerde besluiten
besluit-ondertekenaar Besluitvorming gedelegeerde bevoegdheid β€” Gemachtigde ondertekenaar: ondertekent het besluit via ValidSign
besluit-registratie Besluitvorming gedelegeerde bevoegdheid β€” Registratie & Beheer: registreert en archiveert

Public Affairs and Woo

Role Description
public-affairs Provincial Public Affairs adviser β€” access to the PA-cockpit
pa-author PA Dossierbeheer β€” Auteur: maakt en bewerkt dossiers (create, edit)
pa-editor PA Dossierbeheer β€” Redacteur: + sjablonen beheren en publiceren (templates, publish)
pa-admin PA Dossierbeheer β€” Beheerder: + Archiefwet-archivering en definitief verwijderen (archive, delete)
woo-coordinatie Woo-coΓΆrdinator β€” beheert en verantwoordt Woo-verzoeken (Wet open overheid)

RIP

The candidate groups the RIP process models address their tasks to. A task list shows only the tasks addressed to a role the user holds.

Role Description
rip-aandrager RIP Fase 1 (R2.1) β€” aandrager/indiener: levert het projectplan en intakeformulier aan
rip-adviseur RIP β€” adviseur
rip-adviseur-veiligheid-gezondheid RIP β€” adviseur veiligheid & gezondheid
rip-ao RIP Fase 1 (R2.1) β€” ambtelijk opdrachtgever
rip-beheerder RIP β€” beheerder
rip-beheerder-assetmanagement RIP β€” beheerder assetmanagement
rip-communicatieadviseur RIP β€” communicatieadviseur
rip-concerndirecteur RIP β€” concerndirecteur
rip-databeheerder RIP β€” databeheerder
rip-deelnemers-evaluatie RIP β€” deelnemer evaluatie
rip-deelnemers-psu RIP Fase 1 (R2.1) β€” deelnemers project start-up (PSU)
rip-directievoerder RIP β€” directievoerder
rip-financien RIP β€” financiΓ«n
rip-infra-overleg RIP β€” Infra-overleg
rip-inkoopadviseur RIP β€” inkoopadviseur
rip-inkoopadviseur-werken RIP β€” inkoopadviseur werken
rip-kosten-contractdeskundige RIP β€” kosten- en contractdeskundige
rip-kostenadviseur RIP β€” kostenadviseur
rip-kwaliteit RIP β€” kwaliteitstoetsing
rip-manager-financien RIP β€” manager financiΓ«n
rip-manager-pb RIP Fase 1 (R2.1) β€” manager planvoorbereiding
rip-omgevingsmanager RIP β€” omgevingsmanager
rip-ondersteuner RIP β€” ondersteuner
rip-ontwerper RIP β€” ontwerper
rip-opdrachtnemer RIP β€” opdrachtnemer (externe partij)
rip-pkt RIP β€” projectkwaliteitsteam (PKT)
rip-projectbeheersing RIP β€” projectbeheersing
rip-projectleider RIP Fase 1 (R2.1) β€” projectleider
rip-projectondersteuner RIP β€” projectondersteuner
rip-team RIP Fase 1 (R2.1) β€” RIP-team
rip-technisch-administratief-medewerker RIP β€” technisch-administratief medewerker
rip-technisch-adviseur RIP β€” technisch adviseur
rip-toezichthouder RIP β€” toezichthouder
rip-vestigingsmanager RIP β€” vestigingsmanager

Test users

The export defines 27 test users, all with password test123 and assurance_level = hoog. The ronl-business-api client allows direct access grants, so a test token can be requested with a username and password.

Username municipality organisation_type Realm roles
test-citizen-utrecht utrecht municipality citizen
test-caseworker-utrecht utrecht municipality caseworker
test-citizen-amsterdam amsterdam municipality citizen
test-caseworker-amsterdam amsterdam municipality caseworker
test-citizen-heusden heusden municipality citizen
test-caseworker-heusden heusden municipality caseworker
test-citizen-rotterdam rotterdam municipality citizen
test-caseworker-rotterdam rotterdam municipality caseworker
test-citizen-denhaag denhaag municipality citizen
test-caseworker-denhaag denhaag municipality caseworker
test-hr-denhaag denhaag municipality caseworker, hr-medewerker
test-onboarded-denhaag denhaag municipality caseworker
test-citizen-flevoland flevoland province citizen
test-caseworker-flevoland flevoland province caseworker, besluit-indiener
test-hr-flevoland flevoland province caseworker, hr-medewerker, board-secretary, board-director, hrm-unit, procurement-unit, planning-control-officer, financial-controller, hr-business-partner, personnel-controller
test-mngr-flevoland flevoland province caseworker, manager
test-indiener-flevoland flevoland province caseworker, besluit-indiener
test-besluit-flevoland flevoland province caseworker, besluit-jurist, besluit-bestuursautoriteit, besluit-ondertekenaar, besluit-registratie
test-infra-flevoland flevoland province caseworker, infra-projectteam, infra-medewerker, and all 34 rip-* roles
test-pa-flevoland flevoland province public-affairs, pa-author, pa-editor, pa-admin
test-woo-flevoland flevoland province woo-coordinatie
test-citizen-uwv uwv national citizen
test-caseworker-uwv uwv national caseworker
test-citizen-toeslagen toeslagen national citizen
test-caseworker-toeslagen toeslagen national caseworker
test-citizen-unive unive commercial citizen
test-caseworker-unive unive commercial caseworker

test-hr-denhaag is the primary HR test account β€” it holds the hr-medewerker realm role and can start onboarding processes and view the Afgeronde onboardingen archive. test-onboarded-denhaag simulates an employee who has already been onboarded; logging in with this account triggers an auto-fetch of the completed onboarding record for emp-test-01.

test-hr-flevoland is the Flevoland HR account for onboarding infrastructure employees, and also holds every role of the management capacity claim except manager; test-mngr-flevoland is the manager who starts a claim. test-infra-flevoland is a pre-configured infrastructure team member (employeeId: EMP-FLV-001) who can start and work through the RIP processes.

For Besluitvorming onder gedelegeerde bevoegdheid, test-indiener-flevoland prepares a besluit and test-besluit-flevoland holds the four other lanes. test-caseworker-flevoland, the everyday Flevoland caseworker, can prepare a besluit too. Both besluit accounts have an e-mail address, which signing with ValidSign needs.

test-pa-flevoland opens the PA-cockpit and test-woo-flevoland the Woo board.


Changing the realm

Editing config/keycloak/ronl-realm.json changes a local Keycloak, the next time it imports the file. An existing realm is not imported again, so start from an empty volume:

npm run docker:down:volumes && npm run docker:up

This also removes what was added to the local realm by hand or by script; run scripts/keycloak-add-entra-idp.sh again afterwards if you use the Entra provider locally.

ACC and PROD are not re-imported. An import either skips what already exists or overwrites whole definitions, discarding what those environments configured by hand β€” redirect URIs, web origins, client secrets, the identity provider, roles granted to employees. Their realms are changed through the admin REST API by idempotent scripts in scripts/:

Change Script
New realm roles keycloak-add-rip-roles.sh β€” creates every role in the realm file whose name starts with ROLE_PREFIX (default rip-), and grants them all to GRANT_USER (default test-infra-flevoland for rip-, empty for any other prefix; empty grants nothing)
The ValidSign token claims keycloak-add-token-claim-mappers.sh
The Entra ID identity provider, its token storage, the read-token default role and the broker-roles client mapper keycloak-add-entra-idp.sh

For the besluit roles, for example:

KEYCLOAK_URL=https://acc.keycloak.open-regels.nl ROLE_PREFIX=besluit- GRANT_USER= \
  bash scripts/keycloak-add-rip-roles.sh

Anything else β€” a new test user, a role for one particular user β€” is done in the admin console. See Entra ID β€” Rolling out to an environment for running the scripts.