Schlüsselverwaltung
Wie eine Integration an einen API-Key kommt, wie sie ihn rotiert, was bei Verlust zu tun ist — und warum du als Integrator einen Teil davon nicht selbst erledigen kannst.
Keys, Freigaben und Mandanten-Policies werden ausschließlich in der Plattform-Oberfläche verwaltet
(Endpunkte /api/user/api-keys und /api/admin/api-access — nur mit angemeldetem
Benutzerkonto der Oberfläche erreichbar). Ein API-Key kommt
dort per Design nicht hinein: die Key-Chain matcht nur /api/external/v1/**. Ein Key kann sich also
weder selbst verlängern noch weitere Keys erzeugen.
Die drei Ebenen
| Ebene | Wer richtet sie ein | Was sie festlegt |
|---|---|---|
| Mandanten-Policy | Operator/Admin | Ob der Mandant überhaupt API-Zugriff hat, welche Scopes maximal möglich sind, ob Personen sich selbst Keys ausstellen dürfen, sowie die Grenzwerte für Laufzeit, Anzahl und Rotationsfrist |
| Grant (Freigabe) | Operator/Admin, für eine konkrete Person | Für welchen Mandanten diese Person Keys erzeugen darf, mit welchen Scopes, bis wann, wie viele gleichzeitig |
| API-Key | die Person selbst, im Einstellungsdialog | Anzeigename, Scopes (Teilmenge des Grants), Ablaufdatum |
Wirksam ist immer die Schnittmenge: Key ∩ Grant ∩ Policy. Wird oben etwas entzogen, verliert
der Key es sofort — ohne dass jemand den Key anfasst. Was aktuell wirkt, sagt dir
GET /api/external/v1/me.
Der Weg zu einem Key
- Mandanten freischalten lassen. Der Betreiber legt für den Standort-Root (z. B.
musterhaus) eine Policy an und wählt die maximal erlaubten Scopes. - Freigabe für eine Person beantragen. Ein Grant hängt immer an einem echten Benutzerkonto — nicht an einer Rolle, nicht an einem technischen Konto. Diese Person muss Mitglied des Mandanten sein und aktiv bleiben. Der Antrag sollte Zweck, Scopes und eine Ticket-Referenz nennen; beides wird im Audit-Trail festgehalten.
- Key erzeugen. Die Person öffnet ihre Einstellungen, wählt den Mandanten, vergibt einen sprechenden Anzeigenamen (z. B. „j-lawyer Produktion") und wählt die Scopes aus dem, was der Grant hergibt.
- Key genau einmal abgreifen. Der Klartext-Key wird einmalig angezeigt und ist danach nicht wiederherstellbar. Er gehört sofort in den Secret-Store deiner Integration — nicht in ein Ticket, nicht in ein Chat-Fenster, nicht ins Repository.
- Smoke-Test.
GET /api/external/v1/mebestätigt Key, Mandant und effektive Scopes.
Wen wählt man als Grant-Person?
Der Key sieht nie mehr als die Person dahinter: die fachlichen Abfragen scopen weiterhin auf deren Standort-Mitgliedschaften, und ihre Rechte entscheiden, ob ein Fall abgeschlossen oder wiedereröffnet werden darf. Nimm also keine zufällige Person, sondern eine mit genau dem Zuschnitt, den die Integration braucht — und plane, dass ihr Ausscheiden alle ihre Keys tötet.
Grenzwerte
Die Werte sind Teil der Policy und pro Mandant einstellbar. Die Voreinstellungen:
| Grenze | Voreinstellung | Bedeutung |
|---|---|---|
| Standard-Laufzeit eines Keys | 90 Tage | wenn beim Erzeugen kein Ablaufdatum gewählt wird |
| Maximale Laufzeit | 365 Tage | ein späteres Ablaufdatum wird abgelehnt |
| Gleichzeitig nutzbare Keys je Person und Mandant | 2 | ein Vorgänger in der Rotationsfrist zählt mit |
| Standard-Rotationsfrist | 120 Minuten | Übergangszeit, in der der alte Key noch funktioniert |
| Maximale Rotationsfrist | 1440 Minuten (24 h) | mehr wird auf diesen Wert gekappt |
Ein Key läuft ab, ohne dass jemand etwas tut: Nach dem Ablaufdatum antwortet jeder Request mit
401 API_KEY_INVALID. Plane die Rotation im Kalender ein — es gibt keine Verlängerung eines
bestehenden Keys, nur einen Nachfolger.
Rotation mit Übergangsfrist
Rotation heißt: ein neuer Key entsteht, der alte geht in eine Übergangsfrist
(ROTATION_GRACE) und bleibt bis zu deren Ende gültig. So kannst du deployen, ohne eine Minute
Ausfall.
Der Ablauf aus Integrator-Sicht:
- Rotation in der Oberfläche auslösen und die gewünschte Übergangsfrist wählen (0 bis zum Maximum; 0 bedeutet: der alte Key ist sofort tot).
- Den neuen Key im Secret-Store hinterlegen und ausrollen.
- Mit
GET /meprüfen, dass die Instanzen den neuen Key nutzen — diepublicIdin der Antwort sagt dir, welcher Key gerade spricht. - Die Übergangsfrist vorzeitig beenden, sobald alles läuft (der alte Key wird dann widerrufen).
Randbedingungen:
- Es kann nur eine Rotation gleichzeitig laufen: solange ein Vorgänger in der Übergangsfrist ist, wird eine weitere Rotation abgelehnt.
- Der Vorgänger stirbt automatisch am Ende der Frist — ein Nachlaufen ist nicht möglich, und die Frist lässt sich nicht verlängern.
- Ein rotierter Key wird nie wiederbelebt: Widerruf ist endgültig.
- Die Scopes des Nachfolgers werden erneut gegen Grant und Policy geschnitten — hat sich dort etwas
geändert, kann der neue Key weniger können als der alte. Prüfe nach jeder Rotation
GET /me.
Empfehlung: rotiere planmäßig, deutlich vor dem Ablaufdatum, und behandle Rotation als normalen Betriebsvorgang — nicht als Notfallmaßnahme.
Weitere Lebenszyklus-Zustände
| Zustand | Was er bedeutet | Umkehrbar? |
|---|---|---|
ACTIVE | normal nutzbar | — |
ROTATION_GRACE | Vorgänger einer Rotation, bis graceEndsAt noch nutzbar | endet automatisch |
DISABLED | vorübergehend stillgelegt (z. B. während einer Untersuchung) | ja, wieder aktivierbar |
REVOKED | endgültig widerrufen | nein |
COMPROMISED | wegen eines Vorfalls widerrufen, ohne Übergangsfrist | nein |
Alle vier Zustände außer ACTIVE/ROTATION_GRACE führen bei jedem Request zu
401 API_KEY_INVALID — ununterscheidbar von „Key existiert nicht". Wenn deine Integration plötzlich
401 sieht, ist der Blick in die Verwaltungsoberfläche der schnellste Weg zur Ursache.
Der Grant hat einen eigenen Lebenszyklus: ACTIVE, SUSPENDED (vorübergehend ausgesetzt) und
REVOKED (endgültig; eine erneute Freigabe erzeugt immer einen neuen Grant, alte Keys bleiben
tot). Ein ausgesetzter oder widerrufener Grant legt sofort alle Keys darunter still.
Bei Kompromittierung
Ein Key gilt als kompromittiert, sobald er irgendwo gelandet ist, wo er nicht hingehört: im Repository, im Log, im Ticket, im Screenshot, auf einem verlorenen Laptop.
- Sofort als kompromittiert widerrufen — nicht „deaktivieren", nicht „rotieren mit Frist". Der Incident-Widerruf beendet den Zugang ohne Übergangszeit und ist endgültig. Im Zweifel: alle Keys der Person bzw. des Mandanten auf einen Schlag widerrufen.
- Neuen Key ausstellen und ausrollen. Die Ausfallzeit ist der Preis der Sicherheit — deshalb ist ein zweiter, ungenutzter Reserve-Key selten sinnvoll (er verdoppelt nur die Angriffsfläche); besser ist ein schneller, geübter Deploy-Weg.
- Spur suchen. Jede Erstellung, Rotation, Deaktivierung und jeder Widerruf landet mit Akteur,
Zeitpunkt und Begründung im Audit-Trail des Grants; fehlgeschlagene Authentifizierungen werden
ebenfalls protokolliert. Der
last_used_at-Zeitstempel des Keys zeigt, ob er überhaupt benutzt wurde. Der Betreiber kann daraus rekonstruieren, was mit dem Key passiert ist — nenn ihm diepublicId. - Betreiber informieren, auch wenn du selbst schon widerrufen hast: nur er sieht den vollständigen Audit-Trail und kann beurteilen, ob weitere Mandanten betroffen sind.
Die publicId (der mittlere Block des Keys) ist nicht geheim und darf im Ticket stehen — sie
identifiziert den Key eindeutig. Das Secret nie.
Betriebshygiene
- Ein Key pro Umgebung und Zweck. Die Umgebung steckt im Key-Namen (
usp_dev_…,usp_prod_…), aber ein sprechender Anzeigename erspart im Zweifel die Rätselei. - Scopes minimal. Kein
attachments:writefür eine Integration, die nur liest; keinreference-data:write, wenn niemand den Versicherungskatalog pflegt — dieser Scope wirkt ohnehin nur an einem Operator-Konto. - Nie im Repository, nie im Log. Der Key ist ein Bearer-Credential: wer ihn hat, ist du. Prüfe auch, dass dein HTTP-Client keine Header mitloggt.
- Immer TLS. Ohne verschlüsselte Verbindung ist der Key auf der Leitung lesbar.
GET /mebeim Start deiner Anwendung. Ein früher, klarer Fehler beim Hochfahren ist besser als ein 401 mitten im Sync-Lauf.- 401 alarmiert, 429 wartet. Siehe Fehlercodes.
Verwandte Seiten
- Authentifizierung und Scopes — Key-Format, Header, Scope-Katalog, Rate-Limits.
- Integrator-Kochbuch — die Sync-Schleife in konkreten Aufrufen.