Brainversum · tuxametrics Graph Admin

adr vertraulich owner: matus

ADR-0009: Agent-Provisioning per echtem Keycloak-Admin-Client

ADR-0009: Agent-Provisioning per echtem Keycloak-Admin-Client

Status

Angenommen (2026-08-17). Ergänzt ADR-0007 (erster AGENT-Actor). Löst keine ADR ab.

Kontext

Der einzige agentische Actor dieses Produkts (tuxametrics-autoimprove-agent, siehe ADR-0007) war bisher ein statischer Keycloak-Client: sein Secret steht im Klartext in keycloak/realm-export.json (changeme-local-only) und ist damit für jeden mit Repo-Zugriff identisch und nie rotierbar, ohne die Datei anzufassen und den Realm neu zu importieren.

Anlass war die Frage, ob ein Agent (eine Claude-Session, mit dem Auftrag Autoimprove-Karten zu analysieren) sich damit eigenständig authentisieren kann. dot-platform-service hat für genau dieses Problem einen Mechanismus (dot-ADR-0021, "Echtes Keycloak-Client-Provisioning pro Agent") — auf ausdrücklichen Nutzerwunsch wird er hier generisch nachgebaut, nicht nur für den einen bestehenden Agent fest verdrahtet.

Entscheidung

  1. Neue Entities AgentDefinition/AgentToken in tuxametrics-platform-service, analog zu UserProfileAssignment: eine agentische Identität ist jetzt ein Datensatz in der Authority, kein reiner Realm-Export-Eintrag. AgentToken speichert nur clientId — das Secret wird nie persistiert, nur einmalig in der POST .../tokens-Antwort zurückgegeben (AgentTokenProvisioned).

  2. KeycloakAdminClient-Interface + KeycloakAdminClientImpl (infrastructure/keycloak/) — Quarkus-Port von dot-ADR-0021, verschlankt: ein Realm (digital-labs), ein Provisioning-Pfad (Agent-Clients). Bewusst NICHT übernommen, weil in keiner ADR dieses Produkts verlangt:

    • Kill Switch (active/suspendedReason, dot: platform.agent.set-status) — es gibt keinen Betreiber, der einen Agent im laufenden Betrieb stoppen müsste (ADR-0007: "kein Scheduler, kein Bot").
    • Ephemere Session-Secrets mit TTL (zwirn-ADR-0022) — kein unbeaufsichtigter Agent-Betrieb geplant.
    • e2e-Realm-Ziele (dot-ADR-0031) und dediziertes Service-Client-Provisioning (dot-ADR-0039) — dieses Produkt hat keine e2e-Realm, und der Service-Client-Fall ist mit tuxametrics-autoimprove-service bereits statisch gelöst (ADR-0007).

    Wird eines davon später gebraucht, ist es eine eigene ADR, kein stillschweigender Nachtrag hier.

  3. Eingeschränkter Admin-Client tuxametrics-platform-service-admin (nur realm-management manage-clients, kein manage-users, kein voller Realm-Admin) statt der Bootstrap-Admin- Credentials — dieselbe Abwägung wie in dot-ADR-0021 "Nachtrag": Klartext-Admin-Passwort in Anwendungscode ist ein größeres Risiko als der Komfortgewinn eines Clients weniger.

  4. Fünf neue Capabilities (platform.agent.read/create/delete/link-identity/token.create), allesamt [USER] bzw. [USER, SERVICE]nie [AGENT]: ein Agent, der sich selbst oder einen anderen Agent provisioniert, wäre Identitäts-Spoofing. Governance-Charakter, deshalb naheliegend für platform-owner (wie vid.identity.* und autoimprove.agent-module-scope.* bereits dort).

  5. Keine Kopplung an den einen bestehenden praxis01-vid-idn-agent001. AgentDefinition ist ein generisches Register; der bestehende, statisch verdrahtete Autoimprove-Agent (ADR-0007) läuft unverändert neben diesem Mechanismus weiter und wird nicht automatisch migriert — wer ihn auf ein provisioniertes Secret umstellen will, legt einen AgentDefinition-Eintrag an und verknüpft ihn per linkIdentity mit der bestehenden VID-Identity.

Konsequenzen

Vorteile:

Nachteile/Trade-offs:

Betroffene Regeln

Keine neue Regel — folgt bestehenden Hard Rules (GG-GOV-SECURITY-0005 tenant-skopierte Locators, GG-GOV-SECURITY-0003 Capability-Gate auf jedem Schreib-Endpunkt), maschinell geprüft durch ArchitectureRulesTest/ServiceBaselineTest/TenantLocatorRulesTest/CapabilityGateRulesTest.

Nachtrag (2026-08-27) — Herkunft jetzt Zwirn-ADR-0049, Adoptions-Mechanismus ergänzt

Auf Nutzeranweisung erst geprüft, ob dieser Mechanismus generisch existiert, bevor tuxametrics ihn weiter isoliert pflegt: Zwirns Bestandsaufnahme (../../../zwirn/agentic-engineering/backlog/produkt-generika-inventur-2026-08-20.md, Abschnitt F) hatte den Bedarf bereits benannt — evepop und tuxametrics hatten unabhängig voneinander dasselbe AgentDefinition/AgentToken-Backend gebaut. Der hier gebaute Code wurde deshalb 1:1 nach zwirn-platform-service hochgezogen (Zwirn-ADR-0049) und von dort mit einer Ergänzung zurückgezogen: AgentDefinitionCreate trägt jetzt zusätzlich agentKey/keycloakClientId/userKeyClaim als optionale Overrides. Grund: ohne sie ließe sich tuxametrics-autoimprove-agent (user_key=praxis01-vid-idn-agent001, kein "agent-"/"agent:"- Präfix) nicht adoptieren, sondern nur ein zweiter, paralleler Client erzeugen — genau der Fall, den Punkt 5 oben ("keine Kopplung an den einen bestehenden Agenten") bis heute offengelassen hatte. KeycloakAdminClient.provisionAgentClient nimmt seither bereits aufgelöste Werte entgegen statt sie selbst aus einem agentKey abzuleiten - die Default-Ableitung liegt jetzt in AgentService. Herkunft damit: guidelines/adr/0009 (dieses ADR) → Zwirn-ADR-0049 → zurück hierher, statt weiterhin direkt auf dot-ADR-0021 zu verweisen. mvn -f tuxametrics-platform-service/pom.xml test: 47/47 grün.