WJ-Kreis-Digital-Standard

VereinOnline anzapfen

Teil des WJ-Kreis-Digital-Standards. Referenz-Installation: WJ Konstanz-Hegau (KNH). Stand: 2026-08-14. Faktenbasis: Inventare in meta/ (live, n8n, repo, knowledge).

Jeder WJ-Kreis hat VereinOnline (VO). Damit ist dieses Kapitel das mit dem größten kreisübergreifenden Wert: Was hier steht, könnt ihr eins zu eins anwenden, auch wenn ihr (noch) keine eigene Nextcloud oder n8n-Instanz betreibt. VO ist in unserer Architektur das System of Record für Mitglieder und Events. Alles andere (Nextcloud, Website, Automatisierung) liest aus VO oder schreibt gezielt dorthin zurück, hält aber nie eine eigene Kopie der Wahrheit. Möglich macht das die VO-API, allerdings mit einigen Verhaltensweisen, die man kennen muss, bevor man ihr Produktivdaten anvertraut. Dieses Kapitel dokumentiert die API-Grundlagen, das Service-User-Konzept mit minimalen Rechten und sämtliche Fallen, die wir in der Referenz-Installation selbst erlitten und gelöst haben.

1. API-Grundlagen

1.1 Charakter der API

Die VO-API ist pull-only. Es gibt keine Webhooks: VO meldet sich nie von selbst, wenn sich ein Mitglied ändert oder ein Event angelegt wird. Synchronisation heißt deshalb immer zeitgesteuertes Polling. Unsere Empfehlung: nicht häufiger als alle 5 Minuten pollen. Rate Limits sind undokumentiert, also behandelt die API pfleglich. In der Referenz-Installation pollt der dichteste Workflow (Foto-Drop) alle 10 Minuten, die übrigen alle 4 Stunden oder seltener.

Aufrufe laufen als HTTP-Requests gegen die VO-Instanz des Kreises mit einem ?api=-Parameter, z. B. ?api=GetMembers oder ?api=GetEvents. Eine vollständige Matrix der API-Fähigkeiten (GetEvents, CreateRegistration, CreateSubscriber usw.) liegt in wj/DigitalWorld/vo-integration-capabilities.md.

1.2 URL-Konvention (Verwechslungsgefahr!)

VO betreibt mehrere Umgebungen, und die Namensgebung führt in die Irre:

InstanzPattern
Test/Sandboxhttps://test.vereinonline.org/<KREIS>/?api=...
Staging via VO-Hauptdomainhttps://www.vereinonline.org/<KREIS>/?api=... (trotz "www" NICHT Prod!)
Prod (Live-Daten)Custom-Domain des Kreises ohne Kreis-Prefix, z. B. https://www.wj-konstanz-hegau.de/?api=...

Merkt euch besonders die zweite Zeile: Die URL mit www.vereinonline.org sieht aus wie Produktion, ist es aber nicht. Wer dort testet und sich wundert, warum die Live-Daten fehlen, sitzt dieser Falle auf.

1.3 Authentifizierung

Das Token hat das Format A/<username>/<md5(passwort)> und lässt sich lokal generieren. Übergabe entweder als Authorization-Header oder als URL-Parameter &token=. Zwei Konsequenzen daraus:

  1. MD5 ist kryptografisch gebrochen, aber VO-Stand der Technik. Kompensiert das mit einem starken, langen Passwort pro Service-User und ausschließlich HTTPS-Transport. Beides ist Pflicht, nicht Kür.
  2. Das Token hängt am Passwort-Hash. Token-Rotation heißt also schlicht: Passwort des Service-Users wechseln, Token neu generieren, in der Automation (z. B. n8n-Credential) hinterlegen.

Achtung, das Auth-Verhalten hat eine gefährliche Eigenheit (stiller Fallback auf anonym), die in Abschnitt 3.1 ausführlich beschrieben ist. Lest sie, bevor ihr den ersten Write-Workflow baut.

2. Service-User-Konzept: Least Privilege statt Admin-Token

Die bequeme Abkürzung wäre ein Admin-Account als API-User. Macht das nicht. Ein geleaktes Admin-Token bedeutet Vollzugriff auf alle Mitgliederdaten eures Kreises. Der Standard sieht stattdessen dedizierte Service-User vor, jeder mit der minimalen Rolle für genau seinen Zweck. In der Referenz-Installation sind es drei; für den Einstieg reichen die ersten beiden:

Service-User (Muster)ZweckRechte (minimal)
Lese-User (KNH: eigener Sync-Account)Mitglieder, Events, Gruppen lesen für Sync und Anzeigeread-only, z. B. eventList:r
Write-User (KNH: eigener Write-Account)Event-Anmeldungen und Kontakte/Subscriber schreibenMitglieder lesen + anmelden, sonst nichts
Event-User (KNH: der Event-User)Events anlegen und ändern (CreateEvent, UpdateEvent)nur "Veranstaltungen = ändern/+"

Die Trennung von Lese- und Write-User ist der Kern: Der Sync-User, der ständig im Einsatz ist (Polling alle paar Minuten), kann im schlimmsten Fall nur lesen. Der Write-User kommt nur in den wenigen Workflows zum Einsatz, die tatsächlich nach VO schreiben (bei KNH: Event-Anmeldung, Erstkontakt, Newsletter), und kann selbst dann keine Mitgliederdaten ändern oder löschen.

Drei Betriebsregeln dazu:

Credential-Ablage: Token gehören in den Credential-Store der Automation (n8n-Credentials) bzw. in einen verschlüsselten Vault, niemals in Workflow-JSONs, Repos oder Doku. Dieser Standard nennt deshalb ausschließlich Key-Namen und Platzhalter, nie Werte.

3. Die Verhaltensfallen (alle selbst erlitten)

3.1 Stiller Fallback auf anonym

Ein ungültiges Token erzeugt KEINEN Auth-Fehler. Die API antwortet stattdessen, als wäre niemand angemeldet: leerer Username, anonyme Basisrechte. Sichtbar wird das nur indirekt, etwa an Meldungen wie Zugriff verweigert (... (eventList:r eventAnmelden:ab)).

Praktische Regel: Wenn ihr eine Rechte-Fehlermeldung seht, prüft ZUERST Token und Username, nicht die Rolle. Ein Tippfehler im Passwort sieht in VO exakt so aus wie eine fehlende Berechtigung.

3.2 Die Anonym-Rolle kann Events anmelden

In der Referenz-Instanz hat die anonyme Basis-Rolle die Rechte eventList:r UND eventAnmelden:ab. Das heißt: unauthentifizierte API-Writes (Event-Anmeldungen) sind möglich. In Kombination mit 3.1 entsteht daraus die eigentliche Gefahr: Ein Workflow mit kaputtem Token fällt nicht mit einem Fehler auf, sondern schreibt einfach anonym weiter. Anmeldungen landen dann ohne den erwarteten User-Kontext in VO, und niemand merkt es.

Konsequenzen für euren Kreis:

3.3 Basiskonfiguration gated die Sichtbarkeit: api.getmembers=alle

Ohne den Parameter api.getmembers=alle in der VO-Basis-Konfiguration (Administration, Basis-Konfiguration, Parameter) liefert GetMembers nur "freigegebene" Datensätze. Das ist kein theoretisches Problem: In Konstanz-Hegau kamen so nur 95 von 162 Mitgliedern über die API, und zwar ohne jede Fehlermeldung. Der Fix kam 2026-05-13 vom VO-Support. Ein Sync auf dieser Basis hätte ein Drittel des Kreises schlicht nicht gekannt.

Das Events-Pendant ist api.events.alledaten=ja: Erst damit liefert die API alle Event-Felder unabhängig vom Rollenrecht des abfragenden Users.

Beide Parameter sind NICHT Default. Sie gehören in die Erstkonfiguration jedes Kreises, der die API nutzt (siehe Checkliste). Weitere Basiskonfig-Parameter, die das API-Verhalten verändern können (in der Referenz-Instanz nicht gesetzt, aber bekannt): api.getmembers.datensatz.freigegeben, api.getmembers.einheiten (Cross-Mandant-Sicht), api.getmembers.felder.freigegeben (Feld-Whitelist), api.getmembers.filter, api.getevents=alle|sub|up|eigen. Wenn eure API-Antworten von den Erwartungen abweichen, prüft zuerst diese Parameter.

3.4 Encoding und Transport bei Write-Endpoints

VO behandelt API-Input intern als Latin-1, auch wenn die Doku UTF-8 behauptet (konsistent mit dem ISO-8859-1-CSV-Export). Die Folgen, alle 2026-07-29 in der Referenz-Installation verifiziert:

Und eine Beruhigung für Event-Writes: sichtbar:0, oeffentlich:0 ist bei frisch angelegten Events der Normalzustand, kein Fehler. Nicht "reparieren".

3.5 Feld-Gotchas beim Parsen von GetEvents und GetMembers

Die API liefert Felder in Formaten, die jeden naiven Parser brechen (bestätigt 2026-06-26, der Foto-Drop-Trigger fiel genau darüber):

FeldVerhaltenAbsicherung
zeitkann Stunde-only sein ("10" statt "10:00")Regex /^(\d{1,2})(?::(\d{2}))?/, Minuten-Default 0
anzahltageString oder fehlt komplettNumber(...) || 1
freieplaetzeStringexplizit casten
ortkann leer seinFallback vorsehen
datumverlässlich, immer ISO YYYY-MM-DDder einzige Anker

Außerdem: Der max=N-Parameter bei GetMembers wird ignoriert; Begrenzung geht nur über den filter-Parameter (SQL-where). Zusatzfelder holt ihr über den felder-Parameter im GetMembers-Call statt über einzelne GetMember-Aufrufe pro Mitglied. Jeder parsende Workflow muss diese Edge-Cases abdecken, sonst gibt es stille Ausfälle (silent skips) oder NaN-Werte, die niemand bemerkt.

4. Sicherheits-Baseline für die VO-Basiskonfiguration

Aus den Fallen oben ergibt sich eine kleine, harte Baseline, die jeder Kreis vor dem ersten produktiven API-Einsatz herstellen sollte:

  1. Anonym-Rechte inventarisieren. Welche Rechte hat die Anonym-Rolle eurer Instanz? Alles entziehen, was nicht bewusst öffentlich sein soll, insbesondere Schreibrechte wie eventAnmelden (soweit VO das zulässt).
  2. Service-User statt Admin. Kein API-Zugang über Admin- oder persönliche Accounts. Lese- und Write-User trennen (Abschnitt 2).
  3. Starke Passwörter, HTTPS only. Wegen MD5-Token ist das Passwort die gesamte Verteidigung. Rotation über Passwortwechsel einplanen (z. B. bei Vorstandswechsel oder Verdacht).
  4. Sichtbarkeits-Parameter setzen. api.getmembers=alle und api.events.alledaten=ja in der Basis-Konfiguration, sonst arbeitet ihr auf unvollständigen Daten, ohne es zu merken. Falls euer Kreis die Mitglieder-Sicht bewusst einschränken will: nutzt dafür die expliziten Parameter (Feld-Whitelist, Filter) statt des impliziten Defaults.
  5. Write-Workflows verifizieren ihre Identität. Login-Check oder Response-Inspektion auf den Usernamen, damit der stille Anonym-Fallback auffliegt.
  6. Secrets nur im Credential-Store. Token und Passwörter liegen im n8n-Credential-Store oder einem verschlüsselten Vault. In Doku, Repos und Chats stehen nur Key-Namen und Platzhalter.

Checkliste

Mechanisch abhakbar, in dieser Reihenfolge:

Referenz KNH

So läuft es bei Konstanz-Hegau konkret (Stand 2026-08-13):

Service-User. Drei User nach dem Muster aus Abschnitt 2: der Lese-User (read-only, Rolle "WJ-Bot", seit dem Lockdown 2026-05-13), der Write-User (Anmeldungen und Subscriber) und der Event-User (Event-CRUD). Die Tokens liegen in den n8n-Credentials VO Header Auth (KNH-Prod) und VO Header Auth (KNH-Write) sowie für den Event-User als Key WJ_VO_EVENTS_API_TOKEN im SOPS-Vault.

Lesende Nutzung. Drei aktive n8n-Workflows pollen VO read-only: der Foto-Drop (alle 10 Minuten GetEvents, legt 2 Stunden nach Event-Start einen Upload-Ordner in Nextcloud an), der Event-Reminder (alle 4 Stunden GetEvents, erinnert 7 Tage und 24 Stunden vorher) und der Montagspush (montags 08:00 GetMembers mit felder=vorname,nachname,geburtstag,aufnahmemitglied,rollen für Geburtstage und Jubiläen). Dazu kommt außerhalb von n8n ein Server-Cronjob für den Events-Sync der Website (täglich 06:00 und 16:00, VO als synced source statt Live-Backend).

Schreibende Nutzung. Drei Website-Workflows schreiben über den Write-User nach VO: Event-Anmeldung (GetMembers-Match auf die E-Mail, dann CreateRegistration als Mitglied per userid oder als Gast; E2E verifiziert 2026-07-03), Erstkontakt (CreateSubscriber in die Interessenten-Gruppe, Double-Opt-In-Mail verschickt VO selbst) und Newsletter-Anmeldung (CreateSubscriber in die Newsletter-Gruppe).

Gelebte Lehren. Der api.getmembers=alle-Fix (95 von 162 Mitgliedern sichtbar, behoben 2026-05-13) und die Encoding-Erkenntnisse vom 2026-07-29 stammen direkt aus diesem Setup. Offener Punkt: ob die Anonym-Rolle das eventAnmelden-Recht verlieren kann, ist mit dem VO-Support noch zu klären. Vertiefende Betriebsdoku liegt im wj-Vault unter 08-infrastructure/vereinonline-api-credentials.md (Achtung: enthält historische Klartext-Notizen, nichts davon in Standard-Dokumente übernehmen).

← 03 Office & TalkWeiter: 05 Automatisierungen →