moza-fsc-testnet — een gedeelde FSC-testomgeving (Federated Service Connectivity) op ZAD, waarmee MijnOverheid-Zakelijk-teams federatieve, beveiligde dienstverlening kunnen beproeven. Begonnen voor de FBS-Berichtenbox-PoC, maar generiek: elk team sluit aan als eigen peer.
- Parent-story: MinBZK/MijnOverheidZakelijk#661
- Gerelateerd project: MinBZK/moza-poc-fbs-berichtenbox (de PoC die hiermee gaat testen)
Communicatie in het Nederlands. Code/technische termen in het Engels waar gangbaar. Vaste FSC/infra-idiomen niet vertalen: inway, outway, manager, directory, peer, grant, contract, trust-anchor, passthrough, SNI.
- GEEN fork van de FSC-software. Dit is een deploy- en configuratie-repo die de OpenFSC reference implementation consumeert (via haar container-images en Helm-charts).
- WEL: onze test-CA, group-/peer-configuratie, ZAD-deploy-workflows, contract-bootstrap.
OpenFSC (EUPL-1.2) = reference implementation van de
FSC Core-standaard. Let op: fsc-nlx
is gearchiveerd en verhuisd naar deze repo (nu onderhouden door RINIS). Docs op
docs.open-fsc.nl. Componenten: manager, inway, outway, directory,
controller (beheer-UI), directory-ui (dienstencatalogus), ca-certportal, sni-proxy plus
PostgreSQL. Beheer (dienst aanmelden / afnemer-toegang aanvragen) loopt via de controller-UI met
contract grant→sign→accept — géén eigen dienst/afnemer-administratie (zie docs/ontwerpkeuzes.md).
OpenFSC-keuzes die wij overnemen (en die FBS-integratie versimpelen):
- Peer ID = geldige OIN (afgeleid uit cert
subject.serialNumber); Peer-naam uitsubject.organization. In FBS ís hetmagazijnIdal de afzender-OIN → OIN↔PeerID is 1:1. - Logging-extensie verplicht; CRL-ondersteuning ingebouwd; TLS conform NCSC-richtlijn TLS 2.1.
- Volgt het Digikoppeling REST-API-profiel.
- Trust-anchor = eigen test-CA, GÉÉN PKIoverheid. We draaien een gesloten testnet, dus de group zet een eigen test-CA als anchor (zoals OpenFSC lokaal). PKIoverheid is alleen nodig bij aansluiting op de productie-overheidsfederatie — buiten scope. (Besluit #720.)
- Topologie: één group + één directory + N peers. Elke peer = eigen ZAD-project (project-isolatie). FBS-peers (magazijn-a/-b = providers/inway, uitvraag-org = consumer/outway) eerst; profiel-org later (#730).
- Deploymodel (zie
docs/zad-projecten.md): peer-templates leven hier (source-of-truth), maar deployen gebeurt bij de app (inway/outway co-located met de app voor intra-project DNS). Directory/group draait centraal vanuit deze repo. Spiegelt OpenFSC's layouthelm/deploy/<org>/(per peer) plushelm/deploy/shared/(gedeelde kern). - FBS-integratie = config-only:
berichtenuitvraagrouteert magazijn-calls naar de lokale outway i.p.v. direct, door deMagazijnregister-URL (magazijnen."<OIN>".url) erheen te wijzen.
mTLS-passthrough is bewezen op het ODCN-prod-cluster (beide poorten, eigen cert, cert-binding intact).
- Poort 443 (data Outway→Inway én manager-mesh): OpenShift Route met
passthrough. Schaalt — gedeeld router-IP, routering op SNI-hostnaam. Elke inway én manager krijgt een eigen, stabiele SNI-hostnaam. Manager-mesh op :443 bewezen indocs/spikes/manager-443-sni.md(#723). - Poort 8443/MetalLB (Manager-mesh): vervallen (#723) — mesh loopt op :443-SNI (zie boven). MetalLB-IP's blijven schaars maar zijn voor de mesh niet meer nodig.
edge/reencrypt-terminatie of client-cert-in-header breken de certificate-binding — verboden.- ZAD deployt images, geen Helm. CI gebruikt
RijksICTGilde/zad-actions/deploy(SHA-gepind, zoalsmoza-poc-fbs-berichtenbox) met eencomponents:-lijst van{name, image}. OpenFSC-charts = bron voor image- + env-namen, niet het deploy-artefact. Projectconfig (env_vars, aliases, services, bijlagen, web-publicatie) staat in de Operations Manager UI en gebruikt deploy-variabelen ($DEPLOYMENT_NAME,$DATABASE_*), zodat elk deployment 'm erft;peers/directory/manager.env.exampledocumenteert die waarden maar dwingt niets af. DB-migratie (#723, opgelost): ZAD ondersteunt nog geen args/init-containers → migreren zit in een wrapper-imagedeploy/zad/manager-migrate/(migrate up && servein de entrypoint). - ZAD-pods configureren via env-vars / gemounte files, niet via CLI-args (ZAD ondersteunt nog geen component-args).
ZAD attachments (generiek blok: encrypted opslag, read-only mount in de pod) is sinds
2026-06-29 beschikbaar. Per-peer certs kunnen nu gemount worden — de eerdere blocker
voor #722/#723 is opgeheven.
docs/ ontwerp: topologie.md + ontwerpkeuzes.md; runbooks incl. sleutelbeheer.md
pki/ test-CA als trust-anchor + cert-generatie
group/ group-id, trust-anchor, group rules (TLS)
peers/ per peer: Helm-values + OIN + adressen
contracts/ grant → sign → accept bootstrap
.github/ ZAD deploy/cleanup workflows
- Secrets nooit committen. Sleutels/certs/
.envblijven buiten git (zie.gitignore). Alleen scripts en.example-templates in de repo. - Commentaar: leg het waarom vast (niet-evidente beslissing, security-/contract-invariant),
niet het wat dat de code al toont. Houd het kort: condenseer rationale tot enkele regels; laat
opsommingen en voorbeelden weg die niets verduidelijken. Staat de uitleg al in
docs/? Verwijs ernaar in één regel in plaats van 'm te herhalen — twee kopieën lopen uiteen. Ga uit van werken-naar-productie: geen "PoC"/"voorlopig"/productie-twijfel in comments. Geen verwijzingen naar review-iteratie-bevindingen (K1,B7, etc.) in comments of testnamen — die labels zijn buiten de review-sessie niet terug te vinden en rotten; beschrijf het probleem zelf, niet hoe het ontdekt werd. Verwijs evenmin naar CLAUDE.md-regels of -secties, zodat een comment zonder CLAUDE.md leesbaar blijft. Toekomstig werk mag tijdens een PR metTODO(#nnn)gemarkeerd worden, maar de ticketreferentie moet vóór/bij merge weer verwijderd zijn: een los ticketnummer is indirecte documentatie. Laat de comment zonder het nummer zelf-verklarend achter (wat + waarom), of haal 'm helemaal weg als het werk klaar is. - Git: nooit direct naar
mainpushen — feature branch + PR. Branch-prefixfeature/,fix/,chore/,docs/. Geen reviewer toevoegen bij aanmaken PR.mainis branch-protected (1 review verplicht, conversation-resolution, geen force-push); required checks:lint,Analyze (actions). - CI:
lint.yml(markdownlint + yamllint + actionlint + OpenFSC-versie-consistentie),codeql.yml(Actions-analyse),scorecard.yml(OpenSSF). Actions SHA- of versie-gepind; Dependabot houdt ze wekelijks bij, plus de base-images van de drie migrate-wrappers. Wekelijks houdt de gegroepeerde PR reviewbaar; advisories komen los daarvan binnen via Dependabot security updates (staat aan op de repo). - Waarschuwingen nalopen: loop bij elke wijziging de output van
shellcheck,yamllint,actionlintenmarkdownlint-cli2na en los elke waarschuwing op, of accepteer 'm bewust met reden erbij. "Groen" zegt alleen iets als er geen onverklaarde nieuwe waarschuwingen bij komen; onverklaarde waarschuwingen blokkeren een PR tot ze getrieerd zijn. - OpenFSC-versie: alle componenten draaien in lockstep op één tag; die staat op negen plekken
(drie wrapper-Dockerfiles, drie workflows,
deploy/local/docker-compose.yaml,deploy/local/.env.exampleénopenfsc_min_versioningroup/group-config.yaml). Dependabot ziet alleen de Dockerfiles en groepeert ze in één PR;.github/scripts/bump-openfsc.sh <versie>doet de rest,check-openfsc-version.shfaalt bij een halve bump. Beide scripts hebben een eigen regressietest in de lint-workflow. Ziedocs/openfsc-versiebeheer.md. - AI-verantwoording: AI-bijdragen markeren met
Co-Authored-By-trailer; zieDISCLAIMER.mdendocs/ai-verantwoording.md. Governance/support delegeren naar de MOZa-hoofdrepo; geen eigenSECURITY.md— melden loopt via het org-brede beleid inMinBZK/.github. Operationeel secretbeheer staat indocs/sleutelbeheer.md. ghCLI voor GitHub-operaties.
Volgorde + status = de sub-issues van epic #737
(GitHub sub-issue-volgorde = single source of truth; niet hier dupliceren). [FSC]-issues horen bij
dit repo; [FBS]-issues bij moza-poc-fbs-berichtenbox.
Huidige stap: #725 (peer example-consumer). #724 (example-provider) is de voorloper/template.
Titel en inleiding zijn functioneel, niet technisch. De Product Owner leest mee en moet
aanleiding, effect en acceptatiecriteria kunnen volgen zonder Helm-, OpenShift- of
FSC-implementatiekennis. Geen bestandspaden, file:line-verwijzingen of chart-/env-namen in het
bovenste deel. Technische details horen in een aparte sectie verderop ("Technische context",
"Oplossingsrichtingen"); daar mogen wel concrete paden, componentnamen en opties staan. Formuleer
acceptatiecriteria in termen van gedrag — een peer kan aansluiten, een contract komt tot stand, de
guard faalt bij een halve bump — niet in termen van implementatie. Koppel een issue aan zijn parent
via de GitHub-issue-relatie, niet via een > Onderdeel van #N.-regel in de tekst.
Bevindingen classificeren we op ernst (Hoog/Medium/Laag) met een samenvattingstabel. Hoog pakken we direct aan, Medium in overleg, Laag later. Die labels blijven in de review: ze horen niet in comments of testnamen terecht te komen.
- FSC Core-spec (Logius) — mTLS verplicht, poorten 443/8443
- RFC 8705 — mTLS client-auth + certificate-bound tokens (
cnf.x5t#S256) - OpenFSC · docs.open-fsc.nl