Personio-Vacancy-Sync via öffentlichem XML-Feed — anonymes Pulling als toleriertes Compliance-Risiko
solcom-gmbh.jobs.personio.de/xml via migrate_plus. Der für Mai 2026 erwogene Refactor auf einen authentifizierten v2-REST-Pfad wird verworfen, weil ein Live-Spike nachgewiesen hat, dass die v2-REST-API nur 8 Header-Felder liefert und alle Content-Felder ausschließlich im XML-Feed existieren. Anonymes Pulling wird als toleriertes Compliance-Risiko anerkannt: die Quelle ist Personio-seitig public publiziert, kein Privacy-Surface, keine PII.
Kontext
Der SOLCOM-Karriere-Bereich auf solcom.de spiegelt offene Stellenanzeigen aus Personio in den Drupal-Bundle node/vacancy. Das Modul web/modules/custom/solcom_vacancy zieht die Stellen stündlich via hook_cron aus dem öffentlichen XML-Feed solcom-gmbh.jobs.personio.de/xml; die Migration config/sync/migrate_plus.migration.solcom_vacancy.yml nutzt data_fetcher_plugin: http + data_parser_plugin: xml. Hard-Delete-Sweep über VacancyHardDeleteSubscriber (MigrateEvents::POST_IMPORT) inklusive Empty-Response-Schutz. Datenmodell, Vocabularies und Canvas-Templates sind seit Q2/2025 produktiv.
Im Mai 2026 wurde ein Refactor auf eine authentifizierte v2-REST-API-Spiegelung erwogen (PRD 2026-05-15-personio-rest-import-prd.html, Plan 2026-05-15-001-feat-personio-rest-import.html). Treiber waren Compliance- und IT-Security-seitige Anforderungen, externe Datenquellen mit Service-Identity anzusprechen, sowie ein vermuteter Pattern-Konsistenz-Gewinn mit künftigen externen REST-Syncs (Salesforce-Publication-Sync, ADR-0029).
Der Live-Spike am 2026-05-15 (vollständig dokumentiert in docs/stories/F-280-personio-rest-import.html#spike-findings) gegen Personios v2-REST-API hat die Grundannahme „authentifizierte REST = vollständige Spiegelung" über 2345 Responses und 429 distinct Jobs erschöpfend widerlegt:
| Quelle | Auth | Job-Set | Felder pro Job |
|---|---|---|---|
POST /v1/auth + GET /v2/recruiting/jobs |
Bearer papi-…, opaque, TTL 24h |
429 (inkl. archiviert + Drafts) | 8 Header-Felder: id, name, category, company, department, hiring_team, created_at, updated_at (requirements_parsed_data + total_requirements waren in 0/2345 Samples non-null) |
GET solcom-gmbh.jobs.personio.de/xml |
keine (public) | 32 (nur Career-Site-live) | 15 Content-Felder: id, subcompany, office, department, recruitingCategory, name, jobDescriptions, employmentType, seniority, schedule, yearsOfExperience, keywords, occupation, occupationCategory, salaryInformation |
Damit ist eine vollständige Spiegelung über REST technisch nicht möglich. Die XML-Quelle liefert genau die 32 Career-Site-live-Stellen mit allen 11 Content-Feldern — exakt das, was die Anzeige-Schicht (Vacancy-Card-Listing, Vacancy-Full-Canvas-Template) braucht.
Entscheidung
Der Personio-Vacancy-Sync bleibt unverändert auf dem öffentlichen XML-Feed solcom-gmbh.jobs.personio.de/xml, geführt über das bestehende solcom_vacancy-Modul mit migrate_plus. Authentifizierter v2-REST-Pfad wird verworfen.
Anonymes Pulling wird als toleriertes Compliance-Risiko anerkannt, mit folgender Begründung:
- Die Quelle ist Personio-seitig public publiziert — der XML-Feed ist Career-Site-Embed, kein geschützter Endpoint. Jede Person und jeder Bot kann ihn anonym abrufen.
- Es gibt kein Privacy-Surface: der Feed enthält ausschließlich publizierte Stellenanzeigen, keine PII, keine Bewerber-Daten, keine internen HR-Informationen.
- Eine Authentifizierung würde am Risiko-Profil nichts ändern; ein Service-Identity-Audit-Trail entstünde nur Drupal-seitig, nicht Personio-seitig — die Quelle bleibt unabhängig vom Zugriffsweg dieselbe public-Ressource.
- Eine Authentifizierung würde aktiv Daten-Verlust auslösen (8 statt 15 Felder, Content-Feldern fehlt komplett).
Drupal-Best-Practice für recurring strukturierte XML-Feeds (data_fetcher_plugin: http + data_parser_plugin: xml + MigrateEvents-Sweep) trägt diesen Use-Case nativ; keiner der Trigger für einen Service+Queue-Refactor (komplexe Auth-Flows, instabiles Schema, Webhook-Ingestion, Transaktions-Side-Effects) ist erfüllt.
Rejected alternatives
- Hybrid: REST für Lifecycle, XML für Content. REST würde die Set-Wahrheit über archivierte/Draft-Jobs liefern; XML weiterhin den Content. Verworfen, weil XML bereits exakt die Anzeige-Menge (32 Career-Site-live-Stellen) enthält — die REST-Set-Information (429 inkl. archiviert) hätte keinen Anzeige-Gewinn, würde aber zwei Quellen, zwei Auth-Modi und doppelten Maintenance-Surface erzeugen.
-
Service+Queue-Refactor auf XML (Migrate raus). Voller Umbau ohne user-sichtbaren Gewinn. Migrate-API ist Drupal-idiomatisch für genau diesen Use-Case und bringt ID-Map-basierte Idempotenz, deklarative Process-Pipeline und freie Ops-Tools (
drush migrate:status,migrate:import) mit. Keiner der Service+Queue-Trigger ist erfüllt. Refactor ohne Forcing-Function, MVP-Risiko (08.07.2026). - Pausieren / GA-warten. Personio-Support fragen, ob v2 in 6/12 Monaten Content-Felder bekommt. Verfehlt den MVP-Termin nicht (Status quo läuft), lässt die Compliance-/Audit-Frage aber offen, statt sie zu schließen. Re-Litigation beim nächsten Audit wäre wahrscheinlich.
Consequences
- Der Migrate-Pfad (
config/sync/migrate_plus.migration.solcom_vacancy.yml+solcom_vacancy-Modul inkl.VacancyHardDeleteSubscriber) bleibt unverändert. Kein Refactor-Risiko, kein Deployment-Stress. - Die im superseded PRD/Plan platzierten ADR-Vorhaben „key-Modul-Pattern" und „Service+Queue-Pattern für authentifizierte REST-Syncs" entfallen ersatzlos. Beide waren TBD-Platzhalter und wurden nie geschrieben. Die Nummern 0031–0034 werden parallel im
develop-Branch durch die SF-Publication-Story (P2503-108) belegt; dieses Dokument nimmt daher die nächste freie Nummer 0035. - ADR-0029 (SF-Publication-Hybrid-Architektur) bleibt unverändert in Kraft. Das in F-280 erwogene
drupal/key-Modul-Pattern für authentifizierte externe REST-Syncs ist nicht Teil dieser Entscheidung; falls SF-Publication beim Bau das Pattern adoptieren möchte, ist das eine eigene Entscheidung in der SF-Publication-Story (P2503-108). - ADR-0026 (Vacancy-Ausschluss Editorial-Workflow) bleibt vollumfänglich gültig. Die dort dokumentierte Konsequenz „bei Wechsel auf API-Basis neu bewerten" wird durch diese Entscheidung explizit nicht ausgelöst.
- Das PRD 2026-05-15-personio-rest-import-prd.html wird auf
supersededgesetzt; der Plan 2026-05-15-001-feat-personio-rest-import.html wird aufsupersededgesetzt. Beide bleiben als historisches Spike-Artefakt erhalten. - Die Story F-280-personio-xml-feed.html wird wieder kanonisch (Status
supersededzurückgenommen). Die REST-Variante F-280-personio-rest-import.html bleibt mit Statussupersededals historischer Hub erhalten — die dort dokumentierten Spike-Findings haben dauerhaften Wert. - Das ursprüngliche PRD 2026-05-02-personio-vacancy-integration-prd.html wird reaktiviert (Status
accepted,superseded-by-Meta entfernt, Metasolcom:reactivated-on=2026-05-15gesetzt). Es beschreibt den XML-Migrate-Pfad, der durch diese Entscheidung als kanonisch bestätigt wird. Die zwischenzeitliche Supersession durch das REST-PRD vom 2026-05-15 wird damit aufgehoben (das REST-PRD selbst bleibtsupersededvia diesem ADR). - Beim nächsten Compliance-/IT-Security-Audit ist dieser ADR der Anker für die Frage „warum kein authentifizierter Sync für Personio?". Sollte sich das Personio-v2-Schema in 6/12 Monaten ändern (Content-Felder im REST-Response erscheinen), wird diese Entscheidung neu bewertet — Trigger: ein neuer Spike, der nachweist, dass REST mindestens die heutigen XML-Content-Felder vollständig liefert.