Realm Beheer
Keycloak: realm-inrichting
Bijgewerkt: 15 september 2026.
Deze pagina zegt wat er staat en waar het te vinden is. De inhoudelijke bron is de
repo; wat daar staat is leidend, en deze pagina herhaalt het niet.
Bron: Carta-Ecosystem/Tools/Keycloak/realms/README.md
Plan: Carta-Ecosystem/Docs/McpOAuth.PLAN.md
Wat er nu staat
| Onderdeel | Waar | Toestand |
|---|---|---|
| Keycloak | identity.lead.nl, productie /opt/keycloak, dev /opt/keycloakdev | 26.7.3 |
| Feature cimd | conf/keycloak.conf, regel features=cimd | Aan. Experimenteel |
| Realm carta | https://identity.lead.nl/realms/carta | Aangemaakt, medewerkers moeten er nog in |
| Client claude | realm carta | Public client met PKCE S256, voor claude.ai, Desktop, mobile en Cowork |
| Client scopes mcp:domein en mcp:toets | realm carta | Optional, elk met een audience-mapper |
| Client carta-realm-provisioner | realm master | Service account met create-realm, Signed JWT |
mcp:toets is tijdelijk en wijst naar de MCP-server die nu draait. Hij vervalt bij de
cutover.
Hoe het is ingericht
Realms worden niet met de hand gemaakt. Het script Tools/Keycloak/provision-realm.sh
past een realm toe uit een configuratiemap onder Tools/Keycloak/realms/:
realms/carta/realm.json realms/carta/client-scopes/*.json realms/carta/clients/*.json realms/carta/default-optional-client-scopes
Het script maakt aan wat ontbreekt, werkt bij wat afwijkt en laat met rust wat klopt. Twee
keer draaien geeft hetzelfde resultaat als één keer. Het verwijdert nooit iets: een realm,
client of gebruiker opruimen is een bewuste handeling met de hand. --dry-run toont eerst
wat er zou veranderen.
Een wijziging in de admin-console die niet in de repo staat, is drift en wordt bij de
eerstvolgende run ongedaan gemaakt. Dat is de bedoeling.
De volgorde ligt vast: realm, client scopes, de realm-toewijzing van die scopes, dan pas de
clients. Keycloak kent de optional scopes toe op het moment dat een client wordt
aangemaakt, ook bij een client die Keycloak zelf genereert uit een Client ID Metadata
Document. Ontbreekt de scope dan, dan krijg je een token zonder aud en is dat achteraf
niet te herstellen.
Aanmelden voor het inrichten
Het script meldt zich aan als carta-realm-provisioner met Signed JWT
(private_key_jwt), niet met een client secret en niet met een wachtwoord.
| Wat | Waar |
|---|---|
| Keystore | /etc/carta/keycloak-provisioner.jks op identity.lead.nl, mode 400 |
| Certificaat in Keycloak | realm master, client carta-realm-provisioner, tabblad Keys |
| Wachtwoorden | instance-laag, niet in git (ADR-08) |
Draaien:
export KC_HOME=/opt/keycloak export KC_SERVER=https://identity.lead.nl export KC_PROVISIONER_CLIENT=carta-realm-provisioner export KC_PROVISIONER_KEYSTORE=/etc/carta/keycloak-provisioner.jks ./provision-realm.sh realms/carta --dry-run
KC_SERVER moet de publieke URL zijn, niet localhost. Bij Signed JWT vult kcadm de
aud-claim van de assertie met de opgegeven server-URL, en Keycloak verwacht daar zijn
eigen issuer. Met localhost krijg je Invalid token audience [invalid_client].
Wat dit wel en niet is
Er gaat geen herbruikbaar geheim meer over de lijn: bij elke aanvraag wordt een eenmalige,
kort geldige assertie ondertekend. Een onderschept verzoek is daarmee waardeloos, en er
kan geen secret in een logregel of shell-history belanden.
Dit is geen tweefactor-authenticatie. Het gaat om een machine-client, niet om een
persoon, en het keystore-wachtwoord en de private key staan allebei als bestand op
dezelfde host. Wie die host compromitteert heeft beide, dus de factoren zijn niet
onafhankelijk. Wil je de MFA-eis voor dit account echt afdekken, dan vraagt dat een
TPM- of HSM-gebonden sleutel, of create-realm weghalen bij het geautomatiseerde pad.
Wat handmatig blijft
Client policy profiles en policies staan niet in de repo. De configuratiesleutels van de
client-id-metadata-document-executor zijn geen onderdeel van de gedocumenteerde
admin-API. Die richt je één keer in de console in; een realmexport legt ze daarna vast.
Voor Claude Code: profiel claude-code-cimd-profile met trusted domains claude.ai,
localhost en 127.0.0.1, Restrict same domain uit en Only Allow Confidential Client
uit. Policy claude-code-cimd-policy met conditie client-id-uri, scheme https,
trusted domain claude.ai.
Openstaande punten
| Punt | Status |
|---|---|
| InitialAccessToken in Services/Carta.Mcp/Carta.Mcp.Api/appsettings.json | Geldig tot 2030, staat in git. Intrekken. T14213 stap 1 |
| Dynamic client registration staat aan in carta | Moet bewust dicht volgens besluit O4 |
| plain wordt geadverteerd naast S256 | De client claude dwingt S256 af, een CIMD-client niet |
| Consent-scherm toont de redirect-hostnaam niet | Eis uit de MCP-spec, vraagt een eigen thema |
| Medewerkers zitten nog niet in realm carta | Alle logins lopen nog via master |
| cimd is een experimentele feature op productie | Kan bij een Keycloak-upgrade breken |
Klantrealms
Vallen hier niet onder. Die horen bij de inrichtingstool uit
Docs/CartaOnline-KeycloakIntegratie.PLAN.md §7. Het script hierboven is het leertraject
daarvoor: het toepassen werkt, het datagedreven deel dat de klantenlijst uit GS leest
bestaat nog niet.
- Last Author
- hans
- Last Edited
- Tue, Sep 15, 1:42 PM