CodamAIDocs
Themafertig

Der Abgleich mit Keycloak

Beim Start und auf Knopfdruck bringt CIAS Rollen, Profilattribute und Claim-Mapper in Keycloak auf den Stand. Warum zuerst Keycloak und dann der Katalog und warum nie gelöscht, sondern stillgelegt wird.

Ausprägungen
beim Startauf Anforderungneue Rollezurückgezogene Rolle → stillgelegtPflichtattribut ohne Default → abgewiesen

Worum es geht

Module melden ihre Rollen und Attribute an, siehe Module melden ihre Rollen an. Damit daraus etwas wird, muss jemand Keycloak und den Katalog auf den Stand bringen. Das macht der Abgleich. Er schreibt drei Dinge:

  • das Benutzerprofil in Keycloak: welche Attribute ein Konto haben kann
  • die Client-Rollen und die Claim-Mapper je Modul. Ein Claim-Mapper sorgt dafür, dass ein Attribut im Token des Clients ankommt
  • den Katalog in CIAS

Wann er läuft

AnlassWieWer
beim Startnach dem Hochfahren, wenn codamai.cias.authorization.startup.enabled=truedie Anwendung selbst
auf AnforderungPOST /cias/admin/roles/reconcilenur ein Plattform-Administrator, sonst 403

Einen Zeitgeber gibt es bewusst nicht. Das Benutzerprofil ist in Keycloak ein Dokument, das bei jedem Schreiben ganz ersetzt wird. Zwei Läufe gleichzeitig würden sich gegenseitig überschreiben. Innerhalb eines Prozesses läuft deshalb immer nur ein Lauf: Wer drückt, während einer läuft, bekommt einen Bericht „läuft bereits“ zurück, und es passiert nichts doppelt.

Beim Start legt CIAS vor dem Abgleich noch die Realm-Rollen an, die die Installation in ihrer Konfiguration nennt (startup.realm-roles, etwa user). Die kommen nie aus einer Deklaration.

Drei Phasen: lesen, ablehnen, schreiben

Ein Lauf
  1. 1
    CIAS
    lesen: jede konfigurierte Deklaration abfragen; ein nicht erreichbares Modul wird vermerkt und sonst in Ruhe gelassen
  2. 2
    CIAS
    ablehnen: fehlerhafte Deklarationen fallen heraus, Widersprüche bei Attributen stoppen den ganzen Lauf, Schlüsselkollisionen ihren Client
  3. 3
    CIAS→Keycloak
    schreiben 1: das Benutzerprofil, einmal für alle Module
  4. 4
    CIAS→Keycloak
    schreiben 2: je Modul fehlende Client-Rollen anlegen, dann die Claim-Mapper
  5. 5
    CIAS
    schreiben 3: je Modul den Katalog, in einer eigenen Transaktion
    Ergebnis: Ein Bericht je Modul: was angelegt, geändert, stillgelegt, wieder aufgenommen wurde

Erst alles lesen, dann alles prüfen, dann schreiben. Ein Lauf, der beim Lesen schon schriebe, würde eine widersprüchliche Konfiguration halb anwenden, und niemand wüsste hinterher, welche Hälfte. Die Ablehnungen im Einzelnen stehen unter Wenn CIAS eine Deklaration nicht annimmt.

Zuerst Keycloak, dann der Katalog

Keycloak und CIAS haben keine gemeinsame Transaktion. Scheitert etwas zwischen beiden, bleibt eine Hälfte allein stehen. Die Reihenfolge entscheidet, welche:

Was übrig bleibt, wenn der Lauf in der Mitte scheitert

Wann: Die Rolle ist in Keycloak angelegt, der Katalog wird nicht mehr geschrieben.

Eine Rolle ohne Inhaber in Keycloak ändert für niemanden etwas. Der nächste Lauf trägt sie in den Katalog nach.

Ergebnis: harmlos

Wann: Die Rolle steht im Katalog, fehlt aber in Keycloak.

Ein Administrator vergibt sie, CIAS speichert die Vergabe, und das Token trägt die Rolle trotzdem nicht.

Ergebnis: ein Recht, das CIAS anbietet und nicht liefern kann

Scheitert das Anlegen in Keycloak für ein Modul, meldet der Bericht es als UNPROVISIONED, und sein Katalog bleibt unverändert, auch Umbenennungen und Stilllegungen. Der nächste Lauf holt alles auf einmal nach, denn jeder Schritt lässt sich wiederholen.

Was mit den Rollen eines Moduls passiert

Vorher und nachher, je Rolle

Wann: Das Modul meldet order-export an, der Katalog kennt sie nicht.

Angelegt in Keycloak, eingetragen im Katalog: Eigentümer das Modul, Scope TENANT, Delegation aus der Konfiguration der Installation.

Ergebnis: im Bericht unter defined

Wann: Das Modul meldet order-edit mit neuem Anzeigenamen an.

Anzeigename und Anzeigegruppe werden übernommen. Beschreibung und Delegation bleiben, wie ein Administrator sie gesetzt hat. Dazu sagt das Modul nichts.

Ergebnis: im Bericht unter updated

Wann: Das Modul meldet order-archive nicht mehr an.

Die Rolle wird stillgelegt, mit Datum und Uhrzeit. Sie bleibt in Keycloak, alle Vergaben bleiben. Neu vergeben lässt sie sich nicht mehr.

Ergebnis: im Bericht unter deprecated

Wann: Das Modul meldet eine stillgelegte Rolle wieder an.

Die Stilllegung wird aufgehoben. Die Vergaben waren nie weg, es muss nichts zurückgegeben werden.

Ergebnis: im Bericht unter reinstated

Wann: Das Modul antwortet nicht.

Nichts ändert sich, auch keine Stilllegung. Eine Rolle wird nie stillgelegt, nur weil ihr Dienst gerade neu startet.

Ergebnis: UNREADABLE

Warum stilllegen statt löschen: Würde CIAS eine zurückgezogene Rolle löschen, verlöre jede Person, die sie hat, ihr Recht, nur weil ein Modul seine Liste aufgeräumt hat. Und niemand könnte später nachsehen, dass es die Rolle je gab.

Stillgelegt wird nur, was diesem Modul gehört. Tragen mehrere Module einen Client, legt das Schweigen des einen nie die Rollen des anderen still. Rollen ohne Eigentümer, etwa die Realm-Rollen der Installation, legt kein Abgleich still.

Attribute

Für Attribute gilt dasselbe Prinzip, nur strenger:

  • Ein Attribut, das kein Modul mehr anmeldet, bleibt im Benutzerprofil. Löschen würde den Wert in jedem Konto vernichten. Eine Rolle ist ein Recht, ein Attribut ist Inhalt.
  • Ein Pflichtattribut ohne Standardwert lehnt CIAS ab, samt der ganzen Deklaration dieses Moduls. Konten, die es schon vorher gab, hätten sonst keinen Wert. Das Profil würde dann behaupten, so etwas könne es nicht geben, und Keycloak lehnte danach sogar Änderungen an diesen Konten ab, auch das Sperren.

Mehr unter Attribute anmelden.

Der Bericht

Anfrage
POST /cias/admin/roles/reconcile
Authorization: Bearer <Token eines Plattform-Administrators>
Antwort
{
  "applied": true,
  "modules": [
    { "module": "cias", "client": "cias-backend", "status": "RECONCILED",
      "provisioned": [], "defined": [], "updated": [],
      "deprecated": [], "reinstated": [], … },
    { "module": "cdms", "client": "cdms-backend", "status": "RECONCILED",
      "provisioned": ["cdms-backend/order-export"],
      "defined": ["cdms-backend/order-export"],
      "deprecated": ["cdms-backend/order-archive"], … }
  ],
  "attributes": [],
  "refusals": []
}
StatusBedeutung
RECONCILEDgelesen, in Keycloak angelegt, Katalog geschrieben
UNPROVISIONEDAnlegen in Keycloak gescheitert, Katalog unverändert
UNREADABLEModul nicht abfragbar, nichts verändert
REJECTEDDeklaration nicht annehmbar, nichts davon angewendet
REFUSEDSchlüsselkollision auf dem Client, an diesem Client nichts geschrieben
SKIPPEDder ganze Lauf hat nichts geschrieben, der Grund steht in refusals

Rollen stehen im Bericht immer als client/key, denn der Schlüssel allein sagt nicht mehr, welche Rolle gemeint ist.

Fallen

Weiter

Quellen im Code und in der Wissensdatenbank
  • CIAS/cias-authorization – RoleReconciliationService (execute: lesen, ablehnen, schreiben; writeProfile, provision, deliver, write; ReentrantLock), ReconciliationReport (applied, modules, attributes, refusals, Status)
  • CIAS/cias-authorization – RoleStartupPass (Realm-Rollen der Installation, dann Abgleich; wirft nie), CiasAuthorizationConfiguration (codamai.cias.authorization.startup.enabled, startup.realm-roles)
  • CIAS/cias-authorization – RoleAdminController (POST /cias/admin/roles/reconcile), Role (deprecate, reinstate)
  • CIAS/cias-iam-api – ClientRoleManagementPort.defineRole, UserProfileManagementPort, ClaimMappingPort
  • CIAS/cias-authorization/docs/adr – ADR-023 (Abschnitte 6 und 7), ADR-026, ADR-028, ADR-040
Suchen