Ga naar inhoud

Identity provider koppelen

Volgens het rulebook bepaalt je organisatie zelf wie namens haar de connector beheert. Daarom loggen je beheerders in via je eigen identity provider (IdP), en geef jij daar de rollen. De connector vertrouwt alleen de rollen die je koppelt. De Trust Authority heeft geen toegang tot je gebruikers.

Elke identity provider die OpenID Connect spreekt, werkt: de simulatie gebruikt Keycloak, en voor Microsoft Entra ID is er een instelling. Registreer de connector als client:

Instelling bij je IdP Waarde
soort client vertrouwelijk (confidential), met client-secret
flow authorization code met PKCE (S256)
redirect-URI {BL_PUBLIC_URL}/auth/callback
redirect na uitloggen {BL_PUBLIC_URL}/login
back-channel logout {BL_PUBLIC_URL}/auth/backchannel-logout (aanbevolen, zie hieronder)
scopes openid profile email, en offline_access als je IdP anders geen refresh token geeft
rollen een claim in het ID-token of het access token met de rollen of groepen van de gebruiker

De connector haalt de configuratie van je IdP op via /.well-known/openid-configuration en controleert elk token tegen de gepubliceerde sleutels (RS256, ES256 of EdDSA), ook als het van het token-endpoint zelf komt. Daarna controleert hij issuer, audience (de client-ID), vervaltijd en nonce.

Rol Mag
admin alles, ook de koppeling met de IdP, API-sleutels voor de beheer-API, het telemetrieniveau en de sessies van anderen
operator het dagelijkse werk: systemen, producten, aanvragen, apps en het verzoekenlog
viewer alleen kijken

Je kiest welke claim de rollen bevat, bijvoorbeeld realm_access.roles (Keycloak) of groups, en welke waarden in die claim welke rol geven. Meer waarden per rol mag, gescheiden door komma’s. Wie geen van de gekoppelde waarden heeft, komt niet binnen.

Onder Instellingen, IdP-koppeling, vul je in:

  • de issuer-URL, zoals browsers hem zien;
  • optioneel een interne URL, als de connector de IdP via een ander adres bereikt dan de browser;
  • de client-ID en het client-secret;
  • de rollen-claim en per rol de waarden die hem geven;
  • of de connector om offline_access moet vragen. Laat dat uit voor Keycloak; zet het aan voor een IdP die anders geen refresh token geeft, zoals Entra ID.

Met Koppeling testen controleert de connector de koppeling zonder hem op te slaan. Koppeling opslaan doet dezelfde test eerst en slaat alleen op als niets mislukt:

Controle Wat de connector doet
discovery-document haalt /.well-known/openid-configuration op, via de interne URL als je die invult
issuer vergelijkt de issuer in dat document met de issuer-URL; anders weigert hij later elk token
ondertekeningssleutels haalt de sleutels van de IdP op
client-ID en client-secret vraagt een token met de client credentials grant. Weigert de IdP de client (invalid_client), dan mislukt de test. Mag de client geen eigen token krijgen (unauthorized_client), dan is hij wel herkend; de connector heeft dat token niet nodig.

De redirect-URI en de rollen test de connector niet: die blijken pas bij het inloggen. Daarom vraagt de beheeromgeving om een bevestiging voordat ze opslaat. Kies je een andere issuer of client-ID, dan eindigen alle sessies, ook die van jezelf (zie sessies), en log je meteen opnieuw in via de nieuwe IdP. Zorg vooraf dat de redirect-URI daar geregistreerd is en dat je er een rol admin hebt. Lukt het inloggen daarna niet, zie dan als niemand meer binnenkomt.

Het client-secret staat versleuteld in de database, met de sleutel uit BL_DATA_KEY (zie installeren). De beheer-API geeft het nooit terug.

Bij een nieuwe installatie doe je dit met de setup-code (zie installeren). De eerste keer dat iemand met de rol admin via de IdP inlogt, eindigt de installatiemodus voorgoed.

TechnischDe IdP vooraf instellen in de configuratie

Zolang er geen koppeling in de beheeromgeving is opgeslagen, gebruikt de connector BL_OIDC_ISSUER, BL_OIDC_INTERNAL_URL, BL_OIDC_CLIENT_ID (standaard connector) en BL_OIDC_CLIENT_SECRET. De rollen komen dan uit realm_access.roles, met de waarden admin, operator en viewer, en de connector vraagt niet om offline_access. Een koppeling in de beheeromgeving gaat altijd voor; daarna doen deze variabelen niets meer, tot iemand op de server de koppeling weghaalt met connector reset-idp (zie hieronder).

De connector is een backend-for-frontend: het inloggen bij je IdP gebeurt op de server, en de browser krijgt alleen een cookie (HttpOnly, SameSite=Lax, en Secure zodra BL_PUBLIC_URL met https:// begint, zoals in productie). De sessie staat in Redis, met de refresh token van je IdP erin, versleuteld met BL_SESSION_KEY. Een login bij je IdP is gebonden aan de browser die hem begon: wie de link naar je IdP doorstuurt, logt een ander er niet mee in.

  • Elke 10 minuten controleert een sessie zich bij je IdP. Is het account uitgeschakeld, heeft de gebruiker geen rol meer of is het een andere gebruiker, dan eindigt de sessie direct. Rollen, naam en e-mail komen telkens opnieuw uit de getekende tokens. Een wijziging in je IdP telt dus binnen minuten.
  • Is je IdP onbereikbaar, dan loopt een sessie hooguit een uur na de laatste geslaagde controle door.
  • Een ongebruikte sessie verdwijnt na de levensduur van de refresh token van je IdP (bij Keycloak de idle-tijd van de SSO-sessie), of anders na 24 uur.
  • Geeft je IdP geen refresh token, dan duurt een sessie vast 8 uur, zonder controle.
  • Koppel je een IdP met een andere issuer, dan eindigen alle sessies van de vorige, ook die van jezelf. Je logt daarna in via de nieuwe IdP.

Onder Instellingen, Sessies, zie je je eigen sessies, als admin die van iedereen, met de browser, het tijdstip van inloggen en wanneer de IdP de sessie het laatst bevestigde. Je kunt een sessie daar intrekken.

Wijzigen alleen vanaf de eigen pagina. Een wijziging met de sessiecookie (POST, PUT, PATCH of DELETE) neemt de connector alleen aan van een pagina van de connector zelf. De browser laat dat zien met Sec-Fetch-Site: same-origin, een oudere browser met een Origin gelijk aan BL_PUBLIC_URL, met de poort. Een verzoek van een andere site, ook van een ander subdomein van je eigen domein, krijgt 403 met de code cross_site_request. Een reverse proxy voor de connector moet die headers dus ongewijzigd doorgeven. Scripts en koppelingen gebruiken een API-sleutel of bl; voor hen geldt deze controle niet. De Trust Authority doet hetzelfde.

Back-channel logout. Registreer {BL_PUBLIC_URL}/auth/backchannel-logout bij de client in je IdP. Logt iemand uit bij je IdP, of beëindig je daar zijn sessie, dan stuurt de IdP een getekend logout_token en beëindigt de connector de bijbehorende sessies meteen, in plaats van bij de volgende controle.

TechnischWat de connector controleert bij back-channel logout

De connector controleert de handtekening van het logout_token tegen de sleutels van je IdP, en iss, aud, iat (hooguit 10 minuten oud), het event http://schemas.openid.net/event/backchannel-logout, dat er geen nonce in staat, en jti tegen hergebruik. Daarna beëindigt hij de sessies met die sid, of zonder sid alle sessies van die gebruiker bij deze IdP. Keycloak stuurt bij Afmelden van een gebruiker in de beheerconsole maar voor één van zijn sessies een token; de andere eindigen bij de volgende controle, binnen 10 minuten.

Met bl werk je vanaf de command line met de beheer-API, als jezelf, met je eigen rol:

Terminal window
bl login https://connector.example.nl
bl whoami
bl logs requests --from 2h --level warn
bl logout

bl login gebruikt de device flow (RFC 8628) met de connector als authorization server. bl toont een link naar de pagina Command line in de beheeromgeving, met een code van acht tekens. Daar zie je welke machine en welke versie van bl toegang vraagt, en log je ervoor in bij je IdP. Wie geen browser op dezelfde machine heeft, bijvoorbeeld via SSH, geeft --no-browser mee.

Inloggen bij je IdP keurt nog niets goed. Daarna toont de connector een bevestigingspagina met de code, de machine, het tijdstip van de aanvraag en als wie en met welke rollen bl gaat werken. Je vinkt aan dat de code dezelfde is als in je terminal en kiest Goedkeuren of Weigeren. Zo kan niemand je een link sturen die met jouw lopende sessie bij de IdP stilletjes zijn eigen bl goedkeurt. Keur dus alleen goed als je zelf net bl login startte.

TechnischWat de connector controleert bij het goedkeuren

Na de login bij je IdP bewaart de connector die login 5 minuten en krijgt de browser een cookie alleen voor de bevestiging (HttpOnly, SameSite=Strict, alleen voor /api/v1/cli/consent), geen sessie. Goedkeuren is een POST vanaf de bevestigingspagina: met die cookie, vanaf een pagina van de connector zelf (Sec-Fetch-Site, of anders Origin of Referer) en met de code die de pagina toonde. De bewaarde login is daarna op, ook bij weigeren. Een aanvraag opzoeken of weigeren vóór de login kan alleen een persoon die via je IdP is ingelogd, niet een API-sleutel. De Trust Authority biedt bl login niet aan.

bl krijgt dan een toegangstoken van 10 minuten en een refresh token, allebei gebonden aan een sleutel die alleen op jouw machine staat (DPoP, RFC 9449). Een gestolen token werkt dus niet zonder die sleutel. Een refresh controleert ook je sessie bij de IdP, net als in de browser. De sessie staat onder Sessies, met een label bl, en in het auditlog staat een actie als “via bl”.

Een beheersysteem of script gebruikt een API-sleutel voor de beheer-API, als Authorization: Bearer <sleutel>. Een admin maakt die onder Instellingen, API-sleutels. De sleutel wordt één keer getoond; de connector bewaart alleen een hash. Een API-sleutel heeft de rechten van een operator: hij kan bijvoorbeeld geen IdP koppelen en geen andere sleutels maken. Apps die data ophalen, krijgen geen API-sleutel maar een eigen sleutel onder Apps (zie een app koppelen).

Het break-glass-token (BL_ADMIN_TOKEN) geeft wie het kent admin-rechten, buiten je IdP om. Het is er voor ontwikkelen en testen, en mag alleen in development en tck: in production en acceptance start de connector niet met dit token.

In productie hangt beheer dus volledig aan je IdP. Zorg voor ten minste twee mensen met de rol admin, en test een wijziging van de IdP-koppeling voordat je hem opslaat.

Na een verkeerde koppeling, of als je IdP verdwijnt, kan niemand meer via de beheeromgeving inloggen. Een installatiemodus is er dan niet meer en een break-glass-token ook niet. De weg terug loopt via de server: wie daar een shell heeft, kan de database en de sleutels toch al lezen. Die toegang is hier het vertrouwensanker.

Draai op de server, in de container van de control plane:

Terminal window
docker exec <container> connector reset-idp

Dat haalt de opgeslagen koppeling weg. Herstart daarna de control plane (elke instantie), bijvoorbeeld met docker restart <container>:

  • Staat BL_OIDC_ISSUER in de configuratie, dan geldt na de herstart weer de IdP uit BL_OIDC_* (zie de IdP vooraf instellen). Log daarmee in en koppel opnieuw.
  • Staat die er niet, of geef je --setup mee, dan gaat de installatiemodus weer open. Het commando toont een nieuwe setup-code. Log daarmee in op /login, koppel een werkende IdP en log via die IdP in als admin; daarmee sluit de installatiemodus weer en vervalt de code. De code staat versleuteld in de database tot dan, ook als de connector tussendoor herstart.

Het commando gebruikt dezelfde database en configuratie als de draaiende connector. Het legt de reset vast in het bewijslog, als beheeractie van een beheerder op de server, met de issuer die verdween. Je lidmaatschap, overeenkomsten, systemen en sleutels blijven staan.