Architectuur van een connector
Je draait de connector zelf, in je eigen infrastructuur en naast je eigen systemen. Er is geen centraal platform waar je data doorheen gaat: de Trust Authority laat organisaties toe en houdt het register bij, maar ziet geen data. Deze pagina beschrijft wat je installeert, wat ernaast moet draaien en wat er open moet.
Twee onderdelen, control plane en data plane
Section titled “Twee onderdelen, control plane en data plane”Een connector bestaat uit twee processen. Ze zitten in hetzelfde image
(ghcr.io/buildinglinks/connector), als de programma’s connector en dataplane, en ze delen één
PostgreSQL-database.
- De control plane (
connector, standaard poort 8080) onderhandelt en beslist. Hij beheert de identiteit van je organisatie, publiceert je catalogus, sluit overeenkomsten volgens het Dataspace Protocol, bewaart je lidmaatschapsbewijs en houdt het bewijslog bij. De beheeromgeving in de browser en de beheer-API (/api/v1) horen er ook bij. - De data plane (
dataplane, standaard poort 8090) verplaatst de data. Als datahouder neemt hij verzoeken van andere deelnemers aan op/publicen stuurt hij ze door naar je systemen, alleen binnen een geldige overeenkomst. Als dataontvanger biedt hij je eigen apps een gateway op/gateway. Hij ondertekent elk verzoek en elk antwoord en legt ze vast.
De control plane stuurt de data plane aan met Data Plane Signaling (DPS). Zo bepaalt de control plane wat mag, en controleert de data plane dat bij elk verzoek.
De gebouwservice (image ghcr.io/buildinglinks/building) is optioneel. Hij haalt openbare
gegevens van gebouwen op uit de BAG via PDOK en, met een eigen sleutel, het energielabel uit
EP-online. Hij bewaart foto’s van gebouwen en doet voorstellen voor producten. De control plane
stuurt /api/building/… naar hem door, met de gebruiker en zijn rollen; de browser praat nooit
rechtstreeks met de gebouwservice. Zonder gebouwservice werkt de connector volledig, maar de
beheeromgeving toont dan geen gebouwgegevens zoals adres en luchtfoto.
Wat je ernaast nodig hebt
Section titled “Wat je ernaast nodig hebt”De connector brengt geen eigen database, identity provider of certificaten mee. Die komen uit je eigen omgeving.
- PostgreSQL, met één database voor control plane en data plane. De gebouwservice gebruikt
dezelfde database, in een eigen schema
building. De simulatie en de belastingtests draaien op PostgreSQL 17. - Redis, alleen voor de control plane: sessies van de beheeromgeving en van
bl login, de inlogstatus bij je identity provider, de tellers van de rate limits en een paar vlaggen voor de status. Er staat niets in dat je kwijt kunt raken; valt Redis weg, dan weigert de connector in plaats van ongecontroleerd door te laten. De simulatie draait op Redis 7. - Een identity provider van je eigen organisatie die OpenID Connect spreekt. Je beheerders loggen daarmee in, en jij bepaalt wie welke rol krijgt. De Trust Authority ziet je gebruikers niet. Zie identity provider koppelen.
- Een plek voor de sleutels: een HSM via PKCS#11, Vault of OpenBao, of een bestand. Zie installeren.
- Een reverse proxy met TLS. De connector spreekt zelf alleen HTTP. De proxy geeft control plane en data plane een publiek adres met HTTPS.
- Optioneel: S3-compatibele opslag en een logverzamelaar, als je het verzoekenlog van de data plane wilt bewaren en terugzoeken. Zie monitoring.
Adressen
Section titled “Adressen”Een connector heeft vier adressen die ertoe doen, publiek of intern. Ze zijn allemaal instellingen (zie installeren).
| Adres | Instelling | Voor wie |
|---|---|---|
| De control plane, zoals andere deelnemers hem zien | BL_INTERNAL_URL |
Trust Authority en andere connectors. Hieruit volgt je DID. |
| De beheeromgeving, zoals de browser hem ziet | BL_PUBLIC_URL |
je beheerders, je identity provider (redirect) en bl login |
| De data plane, zoals andere deelnemers hem zien | BL_DATAPLANE_PUBLIC_URL |
data planes van andere deelnemers en control planes van rechthebbenden |
| De gateway, zoals je apps hem zien | BL_DATAPLANE_BROWSER_URL |
je eigen apps; de beheeromgeving toont dit adres als basis-URL |
Draait je control plane op https://connector.example.nl, dan is de identiteit van je connector
did:web:connector.example.nl. Andere deelnemers halen daar zijn DID-document op, met de publieke
sleutels en de adressen van zijn diensten. Het adres moet dus de wortel van een host zijn, en het
moet blijven: een ander adres is een andere identiteit. BL_PUBLIC_URL is meestal hetzelfde adres.
Geef de data plane een eigen hostnaam, bijvoorbeeld https://data.connector.example.nl. Control
plane en data plane hebben allebei een pad /signaling/v1, dus ze kunnen niet zonder meer onder
dezelfde host staan.
Wat er van buiten bereikbaar moet zijn
Section titled “Wat er van buiten bereikbaar moet zijn”Alles hieronder loopt over HTTPS via je proxy. Wie aanroept, bewijst wie hij is met een token dat hij met de sleutel uit zijn DID-document ondertekent, of met een lidmaatschapsbewijs van de Trust Authority.
| Wie | Naar | Waarvoor |
|---|---|---|
| Iedereen | control plane, /.well-known/did.json, did.jsonl, did-witness.json |
je DID-document en de ondertekende historie ervan (did:web en did:webvh) |
| Andere connectors | control plane, /dsp/… en /.well-known/dspace-version |
catalogus, onderhandelingen, overeenkomsten en leveringen volgens het Dataspace Protocol |
| Andere connectors, Trust Authority | control plane, /dcp/… |
je lidmaatschapsbewijs presenteren (DCP); de Trust Authority biedt er ook nieuwe bewijzen aan |
| Trust Authority | control plane, /healthz |
de controle of je connector bereikbaar en gezond is, elke 15 seconden |
| Rechthebbenden en datahouders | control plane, /delegation/v1/… |
erkenning en aanwijzing: leveren namens een ander |
| Data planes van datahouders die voor jou leveren | control plane, /signaling/v1/… |
meldingen over de levering en het ophalen van de overeenkomst |
| Gateways van dataontvangers | data plane, /public/… en /token |
data lezen en sturen binnen een overeenkomst, en het toegangstoken verversen |
| Control planes van rechthebbenden voor wie jij levert | data plane, /signaling/v1/… |
leveringen starten, pauzeren en stoppen |
Niet van buiten bereikbaar hoeven:
- de beheeromgeving,
/api/v1en/auth/…van de control plane: alleen voor je beheerders, je eigen software en je identity provider; - de gateway
/gateway/…van de data plane: alleen voor je eigen apps; /healthzen/readyzvan de data plane: alleen voor je eigen monitoring en de control plane.
Staan BL_PUBLIC_URL en BL_INTERNAL_URL op dezelfde host, scherm de beheeromgeving dan in de
proxy af op pad of op netwerk.
Wat je connector zelf bereikt
Section titled “Wat je connector zelf bereikt”| Naar | Waarvoor |
|---|---|
de Trust Authority (BL_AUTHORITY_URL) |
aanmelding, het register, de heartbeat, het verankeren van het bewijslog en de getuige voor je DID-historie |
| control planes en data planes van andere deelnemers | onderhandelen, data ophalen, tokens verversen; alleen op publieke adressen |
| je identity provider | inloggen en sessies controleren |
| je systemen | de data plane voor de data, op het adres van elk systeem; de control plane voor Systeem testen, Koppeling testen en het ophalen van de punten |
| je sleutelopslag | tekenen met een sleutel in een HSM of Vault |
| PDOK en EP-online | alleen de gebouwservice |
Vertrouwensgrenzen
Section titled “Vertrouwensgrenzen”- Tussen deelnemers vertrouwt niemand een netwerkadres. Elk bericht tussen connectors draagt een handtekening met een sleutel uit het DID-document van de afzender, en een connector toetst het lidmaatschap aan het bewijs van de Trust Authority en aan het register.
- Adressen die een ander kiest belt je connector alleen op een publiek adres, zonder redirects
te volgen. Een tegenpartij kan je connector dus niet naar je eigen netwerk sturen. Staan
deelnemers op een privénetwerk, bijvoorbeeld in een acceptatieomgeving, zet dat netwerk dan in
BL_PRIVATE_NETWORKS. Je eigen systemen, identity provider en de Trust Authority vallen daar niet onder: die stel je zelf in. - Je systemen zien alleen je eigen connector: de data plane voor de data, de control plane voor tests en het ophalen van de punten. Hun adres en sleutel staan alleen in je connector, niet in de catalogus en niet in een overeenkomst. Een verzoek dat buiten de overeenkomst valt, bereikt je systeem niet.
- Control plane en data plane hebben elk een eigen sleutel. De sleutel van de data plane mag in het DID-document alleen authenticeren. Wie hem steelt, kan geen overeenkomsten of protocolberichten namens je organisatie tekenen.
- De beheeromgeving gebruikt je identity provider via de server (BFF): tokens komen niet in de browser. API-sleutels bewaart de connector alleen als hash.
- De gebouwservice vertrouwt de control plane via een gedeeld geheim
(
BL_BUILDING_PROXY_SECRET) en hoort alleen voor de control plane bereikbaar te zijn.
Schalen
Section titled “Schalen”- De control plane mag meer replica’s hebben. Uitgaande berichten staan in een duurzame wachtrij (outbox) in de database, die elke replica afwerkt. Achtergrondtaken, zoals verankeren, de heartbeat en het hercontroleren van lopende leveringen, draaien op één replica tegelijk: die met een lock in PostgreSQL. Stopt die replica, dan neemt een andere het bij de volgende controle over, voor de meeste taken binnen een minuut.
- Van de data plane is per deelnemer precies één instance actief. Hij houdt een lease in de
database. Een tweede instance, bijvoorbeeld tijdens een rolling deploy, antwoordt met
503(standby) en meldt zich op/readyzniet gereed, tot de eerste stopt. Hoeveel één data plane aankan, staat bij dimensionering. - Eén database per deelnemer. De locks gelden per database. Zet je meer deelnemers op één PostgreSQL-server, geef ze dan elk een eigen database, geen eigen schema.
TechnischDe data plane in Kubernetes
Zet de data plane in een StatefulSet met één replica, met liveness op /healthz en readiness op
/readyz. Een StatefulSet start de nieuwe pod pas als de oude weg is. De lease vangt de gevallen
op waarin dat toch niet zo is, zoals een pod die na een netwerkpartitie nog draait.
kind: StatefulSetspec: replicas: 1 template: spec: containers: - name: dataplane image: ghcr.io/buildinglinks/connector:0.2.0 command: ["dataplane"] livenessProbe: { httpGet: { path: /healthz, port: 8090 } } readinessProbe: { httpGet: { path: /readyz, port: 8090 }, periodSeconds: 5 }De data plane controleert zijn lease elke 5 seconden. Een controle die niet binnen 3 seconden
antwoordt, telt als verlies. Zonder lease antwoordt elke route behalve /healthz met 503
(standby), ook /readyz.