Zum Hauptinhalt springen

Benutzerbereitstellung mit SCIM 2.0

fremforge implementiert SCIM 2.0 (RFC 7643/7644), damit dein IdP Forgejo-Benutzer automatisch in deiner Organisation bereitstellen kann: anlegen bei Einstellung, aktualisieren bei geänderten Attributen, deaktivieren bei Austritt. Schluss mit „John ist gerade gegangen – hat jemand daran gedacht, seinen fremforge-Zugang zu entziehen?“ Die Deaktivierung in deinem IdP setzt das SCIM-Flag active um, und fremforge deaktiviert den Forgejo-Benutzer in derselben Minute.

SCIM ergänzt OIDC, ersetzt es aber nicht. SCIM ist das Protokoll für die Bereitstellung. Es überträgt Benutzerdatensätze in fremforge. Angemeldet wird sich weiterhin über deinen separat konfigurierten Anmeldeablauf (OIDC). Die meisten kleinen Teams brauchen SCIM überhaupt nicht. Die manuelle Benutzerverwaltung in der Forgejo-Oberfläche reicht völlig. Richte SCIM erst ein, wenn „Wir haben gerade fünf Leute eingestellt – hat jemand daran gedacht, sie in fremforge anzulegen?“ zu einem echten Problem wird.

Diese Seite ist der Praxisleitfaden, um Okta / Entra / Authentik / jeden SCIM-2.0-IdP anzubinden. Plug-and-play für die großen IdPs; funktioniert mit jedem SCIM-2.0-Client.

Funktionen

FunktionUnterstützt
POST /Users (Bereitstellen)✓
GET /Users/:id (Abfragen)✓
GET /Users (Auflisten, mit Filter userName eq)✓
PATCH /Users/:id (Operationen nach RFC 7644 §3.5.2)✓
PUT /Users/:id (vollständiges Ersetzen)✓
DELETE /Users/:id (Deaktivieren, kein endgültiges Löschen)✓
GET /ServiceProviderConfig✓
GET /ResourceTypes, GET /Schemas (Discovery)✓
POST /Groups / GET /Groups / GET /Groups/:id✓
PATCH /Groups/:id (Mitglieder hinzufügen/entfernen)✓
PUT /Groups/:id (vollständiges Ersetzen)✓
DELETE /Groups/:id (Forgejo-Team löschen + Zuordnung weich löschen)✓
Gruppenfilter displayName eq✓
Bulk-Endpunkte✗ Noch nicht
Filteroperatoren außer eq✗ Nutze mehrere Anfragen
Verschachtelte Gruppen✗ Forgejo bildet sie nicht ab

Einrichtung

Schritt 1: SCIM in fremforge einschalten

  1. Organisationsverwaltung → SSO → SCIM-2.0-Benutzerbereitstellung → klicke auf SCIM aktivieren und Token erzeugen.
  2. Die Seite, die auf den Klick antwortet, zeigt das Bearer-Token einmal an. Kopiere es; du brauchst es für deinen IdP. Das Token steht nie in einer URL, und fremforge zeigt es nicht noch einmal an: Gespeichert wird nur sein SHA-256-Hash. Verlierst du es, klicke auf Token rotieren, um ein neues zu erzeugen.
  3. Notiere dir die auf der Seite angezeigte Basis-URL; sie sieht so aus:
    https://frem.sh/<your-org>/scim/v2

Schritt 2: Deinen IdP verbinden

Okta

  1. Applications → Create App Integration → SCIM 2.0 Test App (Header Auth).
  2. Tab Provisioning → Configure API Integration:
    • Base URL: https://frem.sh/<your-org>/scim/v2
    • Authentication Mode: HTTP Header
    • HTTP Header Name: Authorization
    • HTTP Header Value: Bearer <token from step 1>
  3. Test API Credentials sollte Erfolg melden.
  4. Tab To App → schalte Create, Update und Deactivate ein.
  5. Weise der App Benutzer zu. Okta sendet sie per POST an fremforge.

Microsoft Entra (Azure AD)

  1. Enterprise Applications → New application → Non-gallery → Name „fremforge“.
  2. Provisioning → Get started → Modus = Automatic:
    • Tenant URL: https://frem.sh/<your-org>/scim/v2
    • Secret Token: <token from step 1> (ohne das Präfix Bearer einfügen; Entra ergänzt es)
  3. Test Connection → grüner Haken.
  4. Mappings → nutze die Standardzuordnung für User; das einzige Feld, das oft angepasst werden muss, ist userName: Setze es auf userPrincipalName (die Anmeldung des Benutzers in E-Mail-Form).
  5. Save & Start provisioning.

Authentik

  1. Applications → Providers → Create → SCIM Provider:
    • URL: https://frem.sh/<your-org>/scim/v2
    • Token: <token from step 1>
  2. Binde den Provider an deine Application und weise eine Gruppe zu; die Benutzer in dieser Gruppe werden bereitgestellt.

Generischer SCIM-2.0-IdP

Jeder Client, der die übliche Form Authorization: Bearer <token> gegen eine SCIM-2.0-Basis-URL unterstützt, funktioniert. fremforge veröffentlicht seine Fähigkeiten unter:

GET /<your-org>/scim/v2/ServiceProviderConfig
  • Prüfe diese Antwort, um vor der Integration zu sehen, was unterstützt wird.

Was bei der Bereitstellung passiert

Wenn dein IdP einen Benutzer per POST sendet:

  1. fremforge legt einen Forgejo-Benutzer an (der Benutzername wird aus dem SCIM-userName abgeleitet; Namen in E-Mail-Form werden an Forgejos Regeln [a-z0-9-] angepasst, z. B. alice@acme.example → alice-acme-example).
  2. Der Benutzer wird dem Standardteam Members der Organisation hinzugefügt. Er wird NICHT zum Owner befördert. Die Beförderung zum Admin bleibt bei den Operatoren.
  3. Der Benutzer meldet sich über deine bestehende OIDC-Auth-Quelle an (separat auf der SSO-Seite eingerichtet). SCIM legt den Benutzerdatensatz an; der Anmeldeablauf auf IdP-Seite meldet ihn an.
  4. fremforge schreibt eine Zeile in audit_events mit der Aktion scim.user.create. Sichtbar im Verwaltungs-Tab Audit-Log.

Wenn dein IdP einen Benutzer deaktiviert (PATCH active=false oder DELETE):

  1. fremforge setzt prohibit_login=true beim Forgejo-Benutzer. Sitzungen werden widerrufen und künftige Anmeldungen abgewiesen.
  2. Die SSH-Schlüssel des Benutzers bleiben in Forgejo (sie können nicht zum Pushen genutzt werden, weil der Benutzer gesperrt ist).
  3. Die Mitgliedschaft in der Organisation wird für den Audit-Trail beibehalten. Um sie endgültig zu entfernen, klickt ein Admin der Organisation in der Forgejo-Oberfläche auf Remove from org.

Gruppenbereitstellung

Wenn dein IdP eine SCIM-Gruppe anlegt, macht fremforge Folgendes:

  1. Es legt ein Forgejo-Team in deiner Mandanten-Organisation an. Der Teamname wird aus dem displayName der Gruppe abgeleitet (an Forgejos Regeln [a-z0-9_-] angepasst, höchstens 30 Zeichen).
  2. Es hält die Zuordnung in scim_groups fest, damit spätere PATCH-/PUT-/DELETE-Operationen wieder auf dasselbe Forgejo-Team aufgelöst werden.
  3. Es erlaubt PATCH-Operationen auf members mit op=add / op=remove (RFC 7644 §3.5.2 + Kurzform members[value eq "<id>"]).
  4. DELETE /Groups/:id löscht das zugrunde liegende Forgejo-Team. Die DB-Zeile wird weich gelöscht (deleted_at), damit die Zuordnung externalId↔Team ein erneutes Anlegen derselben IdP-Gruppe übersteht.

Jedes Forgejo-Team gewährt seinen Mitgliedern standardmäßig Schreibzugriff auf alle Repositorys der Organisation (eine Gruppe „Backend“ hat also Schreibzugriff auf jedes Repository). Feinerer Zugriff pro Repository wird von Operatoren in den Forgejo-Teameinstellungen konfiguriert; fremforge-SCIM überträgt keine repository-bezogenen Berechtigungen, da SCIM 2.0 keinen Standard für Attribute zu Repository-Berechtigungen hat.

Einschränkungen zum Start:

  • Die E-Mail ist der Benutzerschlüssel. SCIM identifiziert Benutzer über externalId, die wir als primäre E-Mail-Adresse des Benutzers erwarten. Das passt zu unserer bestehenden OIDC-Einstellung username_claim.
  • Keine verschachtelten Gruppen. Forgejos Teammodell ist flach (ein Benutzer ist in einem Team oder nicht). Verschachtelte Gruppenhierarchien aus deinem IdP werden abgeflacht: Ein Benutzer in Engineering → Backend → API wird Mitglied aller drei entsprechenden Forgejo-Teams.

Token-Rotation

SCIM-Bearer-Tokens sollten regelmäßig rotiert werden. fremforge unterstützt eine Rotation ohne Ausfallzeit mit einem Fenster aus zwei Tokens:

  1. Organisationsverwaltung → SSO → SCIM → klicke auf Token rotieren.
  2. Das neue Token wird einmal auf der Seite angezeigt, die auf den Klick antwortet (nie in einer URL); kopiere es.
  3. Das vorherige Token bleibt gültig, bis du auf Vorheriges Token verwerfen klickst. In diesem Fenster kann dein IdP auf das neue Token wechseln, ohne laufende Bereitstellungsaufrufe zu verlieren.
  4. Trage das neue Token in deinem IdP ein.
  5. Hast du bestätigt, dass das neue Token funktioniert (prüfe einige Zyklen lang den Bereitstellungsstatus im IdP), klicke auf Vorheriges Token verwerfen.

Empfohlener Rhythmus: alle 90 Tage oder bei Personaländerungen, die eine Rotation von Zugangsdaten erfordern.

SCIM ausschalten

Organisationsverwaltung → SSO → SCIM → klicke auf SCIM deaktivieren. fremforge:

  • Löscht die Hashes des aktuellen und des vorherigen Tokens (jede ausstehende IdP-Anfrage bekommt 401)
  • Markiert die Zeile mit enabled=false (im Audit sichtbar)
  • Lässt die Zeilen in scim_users unverändert (erneutes Einschalten stellt aus deinem IdP wieder bereit)

Die Forgejo-Benutzer selbst werden NICHT deaktiviert. Willst du sie alle aussperren, tu das zuerst in deinem IdP und schalte dann SCIM aus.

Fehlerbehebung

„Authorization: Bearer required“ (401) bei jeder Anfrage

Das Bearer-Token kommt nicht bei fremforge an. Häufige Ursachen:

  • Falscher Header-Name: Er muss genau Authorization lauten.
  • Fehlendes Präfix Bearer : Okta ergänzt es automatisch, manche Clients nicht. Prüfe mit tcpdump oder den ausführlichen Logs des IdP, was dein IdP tatsächlich sendet.
  • Token widerrufen: Hast du rotiert und das vorherige verworfen, ist das alte Token ungültig. Füge das aktuelle erneut ein.

„userName is required“ (400) bei POST

Dein IdP ordnet userName keinen sinnvollen Wert zu. In Entra heißt das oft, dass der UPN des Benutzers nicht gesetzt ist; ordne userName dann mail oder einem ähnlichen, nicht leeren Attribut zu.

Benutzer sind bereitgestellt, können sich aber nicht anmelden

SCIM legt nur den Benutzerdatensatz an. Der Anmeldeablauf nutzt deine separat konfigurierte OIDC-Auth-Quelle. Prüfe:

  1. Für den Benutzer ist unter Organisationsverwaltung → SSO → Auth-Quellen eine OIDC-Auth-Quelle eingerichtet.
  2. Die Identität des Benutzers auf IdP-Seite (E-Mail, Principal Name) stimmt mit dem userName überein, den du per SCIM bereitgestellt hast.
  3. Die Anmeldeseite unter frem.sh/user/login?redirect_to=/<your-org> zeigt die SSO-Schaltfläche.

Der Filter funktioniert nicht für email eq oder andere Operatoren

Wir unterstützen nur userName eq "<value>". Alles andere liefert eine leere Liste. Die meisten IdPs brauchen nur userName eq zur Deduplizierung; prüfe in ihren Bereitstellungslogs, welche Filterformen sie senden, und sag uns Bescheid, wenn du weitere Operatoren brauchst (an support@frem.sh).

Audit-Trail

Jede durch SCIM ausgelöste Aktion wird im Audit-Log der Organisation mit actor=system erfasst (denn der Akteur ist „dein IdP“, kein angemeldeter Benutzer) und mit einer dieser Aktionen:

  • scim.enabled / scim.disabled: Aktionen in der Operator-Oberfläche
  • scim.token.rotated / scim.token.previous-dropped: Aktionen in der Operator-Oberfläche
  • scim.user.create: POST des IdP
  • scim.user.update / scim.user.replace: PATCH/PUT des IdP
  • scim.user.deactivate / scim.user.reactivate: Änderung des active-Flags durch den IdP
  • scim.group.create / scim.group.update / scim.group.replace / scim.group.delete: Gruppen-Lebenszyklus im IdP
  • dieselben Aktionen landen im Audit-Teil des Datenexport-Bundles

Querverweise