Der Abgleich holt heute. Ein Identitätsanbieter kann auch schicken — authentik, Entra ID und
Okta sprechen dafür SCIM 2.0. Das ist der Weg für Häuser, die Laufzettel keinen Lesezugriff auf ihr
Verzeichnis geben wollen oder aus einem Netz heraus betreiben, das das Verzeichnis nicht erreicht.
Setzt #028 voraus: die Quellenart SCIM braucht die Weiche.
Zu entscheiden
Ein Token je Quelle, als Hash gespeichert — Empfehlung, dasselbe Verfahren wie beim
lokalen Passwort (argon2). Es wird einmal angezeigt und ist danach nicht mehr lesbar. Das
Token identifiziert die Quelle und damit den Kunden; es ist der einzige Mandantenbeweis, den
ein Push mitbringt.
Was bei DELETE /Users/{id} geschieht:aktiv = false, nicht löschen. Das ist die Regel
des ganzen Projekts, und ein Identitätsanbieter, der löschen will, bekommt 204 — aber die
Zeile bleibt, weil Läufe an ihr hängen. Das muss in der Anleitung stehen, sonst wirkt es wie
ein Fehler.
Aufgaben
Route Handler unter src/app/api/scim/v2/: Users (GET mit Filter userName eq, POST), Users/{id} (GET, PUT, PATCH, DELETE), dazu ServiceProviderConfig, Schemas, ResourceTypes — ohne die drei weigern sich manche Anbieter, überhaupt anzufangen
Jeder dieser Handler prüft selbst: das Token, und daraus die Quelle und den Kunden. Die
Hülle unter (app) liegt hier nicht darüber (CLAUDE.md)
Zuordnung: externalId → externeId, userName → upn, name.givenName/familyName, emails[primary] → mail, active → aktiv, urn:ietf:params:scim:schemas:extension:enterprise:2.0:User
für department und manager
Antwortform nach RFC 7644: schemas, id, meta.resourceType, meta.location, bei Listen totalResults/itemsPerPage/startIndex; Fehler als urn:ietf:params:scim:api:messages:2.0:Error
PATCH mit op: add|replace|remove auf den Pfaden, die die Anbieter wirklich schicken —
nicht der ganze Standard
Idempotenz: zweimal dasselbe POST ergibt 409, nicht eine zweite Person
Protokolleintrag je Vorgang, mit der Quelle als Urheber (Systemlauf, kein Benutzer)
Admin → Verzeichnis: Token erzeugen, einmal anzeigen, widerrufen; letzte Zustellung sichtbar
Anleitung Kapitel 06: Einrichtung in authentik und in Entra ID
Akzeptanzkriterien
Test gegen aufgezeichnete Anfragen von authentik und Entra ID (Form, nicht erfunden):
anlegen, aktualisieren, deaktivieren, wieder aktivieren
Test: ohne Token 401, mit fremdem Token kein Zugriff auf die Personen einer anderen Quelle
Test: DELETE setzt aktiv = false und löscht nichts
Test: zweimal dasselbe POST ergibt 409 und keine zweite Zeile
Test: das Token steht nur als Hash in der Datenbank und in keiner Antwort
Test: eine Quelle der Art SCIM wird vom Zeitplan nicht abgeglichen — sie bekommt
geschickt
Quelle im Repo: docs/issues/029-scim-endpunkt.md
## Ziel
Der Abgleich holt heute. Ein Identitätsanbieter kann auch **schicken** — authentik, Entra ID und
Okta sprechen dafür SCIM 2.0. Das ist der Weg für Häuser, die Laufzettel keinen Lesezugriff auf ihr
Verzeichnis geben wollen oder aus einem Netz heraus betreiben, das das Verzeichnis nicht erreicht.
Setzt [#028](028-graph-quelle.md) voraus: die Quellenart `SCIM` braucht die Weiche.
## Zu entscheiden
- [ ] **Ein Token je Quelle, als Hash gespeichert** — Empfehlung, dasselbe Verfahren wie beim
lokalen Passwort (argon2). Es wird **einmal** angezeigt und ist danach nicht mehr lesbar. Das
Token identifiziert die Quelle und damit den Kunden; es ist der einzige Mandantenbeweis, den
ein Push mitbringt.
- [ ] **Was bei `DELETE /Users/{id}` geschieht:** `aktiv = false`, nicht löschen. Das ist die Regel
des ganzen Projekts, und ein Identitätsanbieter, der löschen will, bekommt `204` — aber die
Zeile bleibt, weil Läufe an ihr hängen. Das muss in der Anleitung stehen, sonst wirkt es wie
ein Fehler.
## Aufgaben
- [ ] Route Handler unter `src/app/api/scim/v2/`: `Users` (GET mit Filter `userName eq`, POST),
`Users/{id}` (GET, PUT, PATCH, DELETE), dazu `ServiceProviderConfig`, `Schemas`,
`ResourceTypes` — ohne die drei weigern sich manche Anbieter, überhaupt anzufangen
- [ ] **Jeder dieser Handler prüft selbst**: das Token, und daraus die Quelle und den Kunden. Die
Hülle unter `(app)` liegt hier nicht darüber (CLAUDE.md)
- [ ] Zuordnung: `externalId` → `externeId`, `userName` → `upn`, `name.givenName`/`familyName`,
`emails[primary]` → `mail`, `active` → `aktiv`, `urn:ietf:params:scim:schemas:extension:enterprise:2.0:User`
für `department` und `manager`
- [ ] Antwortform nach RFC 7644: `schemas`, `id`, `meta.resourceType`, `meta.location`, bei Listen
`totalResults`/`itemsPerPage`/`startIndex`; Fehler als `urn:ietf:params:scim:api:messages:2.0:Error`
- [ ] `PATCH` mit `op: add|replace|remove` auf den Pfaden, die die Anbieter wirklich schicken —
nicht der ganze Standard
- [ ] Idempotenz: zweimal dasselbe `POST` ergibt `409`, nicht eine zweite Person
- [ ] Protokolleintrag je Vorgang, mit der Quelle als Urheber (Systemlauf, kein Benutzer)
- [ ] Admin → Verzeichnis: Token erzeugen, einmal anzeigen, widerrufen; letzte Zustellung sichtbar
- [ ] Anleitung Kapitel 06: Einrichtung in authentik und in Entra ID
## Akzeptanzkriterien
- [ ] Test gegen **aufgezeichnete Anfragen** von authentik und Entra ID (Form, nicht erfunden):
anlegen, aktualisieren, deaktivieren, wieder aktivieren
- [ ] Test: ohne Token `401`, mit fremdem Token kein Zugriff auf die Personen einer anderen Quelle
- [ ] Test: `DELETE` setzt `aktiv = false` und löscht nichts
- [ ] Test: zweimal dasselbe `POST` ergibt `409` und keine zweite Zeile
- [ ] Test: das Token steht nur als Hash in der Datenbank und in keiner Antwort
- [ ] Test: eine Quelle der Art `SCIM` wird vom Zeitplan **nicht** abgeglichen — sie bekommt
geschickt
---
Quelle im Repo: `docs/issues/029-scim-endpunkt.md`
florian.wilde
added this to the v0.2.0 milestone 2026-10-04 16:19:16 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Ziel
Der Abgleich holt heute. Ein Identitätsanbieter kann auch schicken — authentik, Entra ID und
Okta sprechen dafür SCIM 2.0. Das ist der Weg für Häuser, die Laufzettel keinen Lesezugriff auf ihr
Verzeichnis geben wollen oder aus einem Netz heraus betreiben, das das Verzeichnis nicht erreicht.
Setzt #028 voraus: die Quellenart
SCIMbraucht die Weiche.Zu entscheiden
lokalen Passwort (argon2). Es wird einmal angezeigt und ist danach nicht mehr lesbar. Das
Token identifiziert die Quelle und damit den Kunden; es ist der einzige Mandantenbeweis, den
ein Push mitbringt.
DELETE /Users/{id}geschieht:aktiv = false, nicht löschen. Das ist die Regeldes ganzen Projekts, und ein Identitätsanbieter, der löschen will, bekommt
204— aber dieZeile bleibt, weil Läufe an ihr hängen. Das muss in der Anleitung stehen, sonst wirkt es wie
ein Fehler.
Aufgaben
src/app/api/scim/v2/:Users(GET mit FilteruserName eq, POST),Users/{id}(GET, PUT, PATCH, DELETE), dazuServiceProviderConfig,Schemas,ResourceTypes— ohne die drei weigern sich manche Anbieter, überhaupt anzufangenHülle unter
(app)liegt hier nicht darüber (CLAUDE.md)externalId→externeId,userName→upn,name.givenName/familyName,emails[primary]→mail,active→aktiv,urn:ietf:params:scim:schemas:extension:enterprise:2.0:Userfür
departmentundmanagerschemas,id,meta.resourceType,meta.location, bei ListentotalResults/itemsPerPage/startIndex; Fehler alsurn:ietf:params:scim:api:messages:2.0:ErrorPATCHmitop: add|replace|removeauf den Pfaden, die die Anbieter wirklich schicken —nicht der ganze Standard
POSTergibt409, nicht eine zweite PersonAkzeptanzkriterien
anlegen, aktualisieren, deaktivieren, wieder aktivieren
401, mit fremdem Token kein Zugriff auf die Personen einer anderen QuelleDELETEsetztaktiv = falseund löscht nichtsPOSTergibt409und keine zweite ZeileSCIMwird vom Zeitplan nicht abgeglichen — sie bekommtgeschickt
Quelle im Repo:
docs/issues/029-scim-endpunkt.md