Zum Inhalt springen

Authentifizierung

Diese Seite zeigt, wie sich Menschen bei OpenBot anmelden und wie Programme die API aufrufen. Eine Person meldet sich einmal im Browser an. Danach erstellt sie User-Tokens für Skripte und Dienste.

Es gibt zwei Wege, die fachlichen Routen unter /v1 aufzurufen:

Weg Wer ihn nutzt Was du sendest
User-Token Skripte, Backend-Dienste, Bots Authorization: Bearer <token>
Session-Cookie Ein Browser-Client auf dem OpenBot-Origin Das Cookie __Host-openbot-session

Beide Wege brauchen für jeden Aufruf eine Berechtigung. Siehe Berechtigungen.


Anmelden

OpenBot speichert keine Passwörter. Es nutzt OpenID-Connect-Anbieter. OpenID Connect (OIDC) ist ein Standard. Damit prüft ein anderer Dienst, wer eine Person ist. Es gibt zwei Arten von Anbietern:

  • Der Platform-Anbieter meldet Menschen für die ganze Platform an. Ein Platform-Admin legt ihn fest. Siehe Den Platform-Anbieter einrichten.
  • Eine SSO-Verbindung ist der Anbieter einer einzelnen Organisation. Sie meldet Menschen an, deren E-Mail zu den geprüften Domains dieser Organisation gehört. Siehe SSO und Domains.

Um eine Anmeldung zu starten, sendet dein Client diese Anfrage vom OpenBot-Origin:

Terminal window
curl -X POST https://api.example.com/auth/sign-in \
-H "Origin: https://api.example.com" \
-H "Content-Type: application/json" \
-d '{"email":"ada@example.com","returnTo":"/settings/keys"}'
{ "url": "https://id.example.com/authorize?..." }

Beide Felder sind optional. OpenBot wählt den Anbieter nach der Domain von email. Hat die Domain eine SSO-Verbindung, führt die url dorthin. Sonst führt sie zum Platform-Anbieter. Gibt es keins von beiden, antwortet OpenBot mit 503 und SignInUnavailable.

Schick den Browser zu dieser url. Die Antwort setzt auch das Cookie für den Anmeldestatus. Nach der Anmeldung schickt der Anbieter den Browser zurück zu OpenBot. OpenBot setzt das Session-Cookie und schickt den Browser zu returnTo. Siehe Rückkehrpfade. Wenn die Anmeldung fehlschlägt, geht der Browser zu /auth/error?error=<code> und bekommt kein Cookie.

Better-Auth-Routen

OpenBot nutzt Better Auth für die Anmeldung. Better Auth stellt seine Routen unter /auth/* bereit, so wie es sein Effect-Leitfaden zeigt. Diese Routen stehen nicht in der API-Referenz. Die Better-Auth-Dokumentation beschreibt sie.

Du kannst sie trotzdem direkt nutzen. Der Platform-Anbieter hat die Anbieter-ID oidc und den Callback /auth/callback/oidc. Eine SSO-Verbindung nutzt ihre eigene ID als Anbieter-ID. Ihr Callback ist /auth/callback/<connectionId>.

Terminal window
curl -X POST https://api.example.com/auth/sign-in/social \
-H "Origin: https://api.example.com" \
-H "Content-Type: application/json" \
-d '{ "provider": "oidc", "callbackURL": "https://api.example.com/settings/keys" }'

Die callbackURL muss auf dem OpenBot-Origin liegen. Wenn nicht, antwortet Better Auth mit 403.

Den Platform-Anbieter einrichten

Registriere OpenBot als Client bei deinem Anbieter. Nutze <publicOrigin>/auth/callback/oidc als Redirect-URI. OpenBot fragt nach den Scopes openid profile email.

Dann gib OpenBot den Anbieter. Auf einer neuen Platform macht das das Einrichtungsprogramm mit --oidc-issuer, --oidc-client-id und --oidc-client-secret. Später ändert ein Platform-Admin ihn mit PATCH /v1/platform/settings. Siehe Platform.

Einstellung Wert
identityProvider.issuer Die Issuer-URL, zum Beispiel https://id.example.com. HTTPS, ohne Schrägstrich am Ende.
identityProvider.clientId Die Client-ID vom Anbieter.
identityProvider.clientSecret Das Client-Secret. Lass es bei einem öffentlichen Client weg.
publicOrigin Der öffentliche HTTPS-Origin von OpenBot, zum Beispiel https://api.example.com.

Ohne Client-Secret meldet sich OpenBot als öffentlicher Client mit PKCE an. PKCE ist eine Prüfung, die den Anmeldecode schützt. Eine Platform kann auch gar keinen Anbieter haben. Dann melden sich Menschen nur über SSO-Verbindungen an.

Entwicklungskonto

Der Entwicklungsserver (devenv shell -- pnpm dev) nutzt ein lokales Testkonto und keinen Anbieter. Das Konto ist developer@localhost.test, und es ist ein Platform-Admin. Nur der Einstiegspunkt für die Entwicklung bietet das an. Das Produktionsprogramm tut das nie. Siehe Konfiguration.

Dieser Befehl meldet dich an und speichert das Cookie in einer Datei:

Terminal window
curl -c cookies.txt -X POST https://localhost:8443/auth/development/sign-in \
-H "Origin: https://localhost:8443" \
-H "Content-Type: application/json" \
-d '{}'

Die Anmeldung lesen und beenden

GET /auth/session gibt das angemeldete Konto und seine Organisationen zurück. Es braucht das Session-Cookie.

{
"userId": "u_123",
"profile": {
"name": "Ada",
"email": "ada@example.com",
"emailVerified": true
},
"memberships": [
{
"organizationId": "org_8f3a",
"name": "Example",
"status": "active",
"roles": ["member"]
}
],
"platformAdmin": false,
"expiresAt": "2026-11-19T10:00:00.000Z"
}
Feld Was es ist
memberships Die Organisationen des Kontos, mit seinem Status und seinen Roles in jeder davon.
platformAdmin true, wenn das Konto ein Platform-Admin ist. Dann kann es /v1/platform nutzen. Siehe Platform.

POST /auth/sign-out beendet die Anmeldung. Es ist eine Better-Auth-Route. Sende einen JSON-Body ({}) und den Header Origin (siehe unten). Die Antwort ist 200.


Mitgliedschaft

Eine Platform hat viele Organisationen. Ein Konto kann Member (Mitglied) in vielen davon sein. Wenn sich ein Konto anmeldet, prüft OpenBot, wohin es gehört:

  1. Es tritt der Organisation bei, die die Domain seiner geprüften E-Mail bestätigt hat, wenn diese Organisation joinByDomain erlaubt.
  2. Es tritt der Organisation seiner SSO-Verbindung bei, wenn es sich über eine angemeldet hat.
  3. Wenn es dann noch keine Organisation hat und die Platform allen erlaubt, eine zu erstellen, bekommt es eine neue Organisation mit dem Namen “Personal”. Dort ist es der Super Administrator.
  4. Sonst hat es keine Organisation. Routen einer Organisation antworten dann mit 403 und MembershipRequired.

OpenBot macht diese Prüfungen auch bei jeder Anfrage mit dem Session-Cookie. Siehe Organisation.

Ein gesperrtes Member bekommt 403 mit MembershipRequired, wenn es das Cookie nutzt. Seine Tokens funktionieren sofort nicht mehr und bekommen 401 mit AuthenticationRequired.

Eine Organisation wählen

Eine Anfrage mit dem Session-Cookie muss sagen, in welcher Organisation sie handelt. Sende die ID im Header OpenBot-Organization:

Terminal window
curl -b cookies.txt \
-H "OpenBot-Organization: org_8f3a" \
https://api.example.com/v1/sessions
  • Ohne den Header nutzt OpenBot deine einzige aktive Organisation.
  • Wenn du mehr als eine aktive Organisation hast und keinen Header sendest, antwortet OpenBot mit 400 und OrganizationRequired.

Ein User-Token gehört zu einer Organisation. Es ignoriert den Header.


Nach der Anmeldung hat der Browser das Cookie __Host-openbot-session. Es ist Secure, HttpOnly und SameSite=Lax.

  • Eine Anmeldung gilt 30 Tage.
  • OpenBot verlängert sie nach einem Tag Nutzung.

Die Origin-Regel

Ein Cookie geht mit jeder Anfrage des Browsers mit, auch von anderen Websites. Darum prüft OpenBot, woher ein Schreibzugriff kommt. Wenn du das Cookie nutzt, muss jede Anfrage mit POST, PUT, PATCH und DELETE einen Header Origin senden. Der Header muss genau gleich publicOrigin in den Platform-Einstellungen sein. Sonst antwortet OpenBot mit 403 und ForbiddenOrigin.

Terminal window
curl -b cookies.txt \
-H "Origin: https://localhost:8443" \
-H "Content-Type: application/json" \
-d '{"title":"Notes"}' \
https://localhost:8443/v1/sessions

Anfragen mit einem User-Token brauchen den Header Origin nicht.


User-Tokens

Mit einem User-Token kann ein Programm für dich handeln. Ein Token kann nie mehr tun als du. Es kann auch eigene Policies haben, damit es weniger tut. Siehe Berechtigungen.

Du kannst Tokens mit dem Session-Cookie verwalten oder mit einem Token, das die Berechtigung tokens.write hat. Ein Token ohne Policies kann keine Tokens verwalten.

Ein Token gehört zu einer Organisation: zu der Organisation der Anfrage, die es erstellt hat. Mit dem Cookie sendest du den Header OpenBot-Organization, um sie zu wählen. Siehe Eine Organisation wählen.

Die vollständigen Formen findest du in der Referenz zu User-Tokens.

Ein Token erstellen

Terminal window
curl -b cookies.txt \
-H "Origin: https://api.example.com" \
-H "Content-Type: application/json" \
-d '{"name":"CI bot","expiresInDays":90}' \
https://api.example.com/v1/user/tokens
Feld Regeln
name Pflicht. 1 bis 80 Zeichen, nachdem Leerzeichen am Anfang und Ende entfernt sind.
expiresInDays Optional. Eine ganze Zahl von 1 bis 365. Lass es weg, wenn das Token funktionieren soll, bis du es widerrufst.
policies Optional. Policies, die das Token begrenzen. Lass es weg, um alles zu erlauben, was du tun kannst, außer tokens.read und tokens.write.

OpenBot antwortet mit 201:

{
"token": {
"id": "5f0c2a8e-7d1b-4c3e-9a55-2b6f1e8d4c10",
"name": "CI bot",
"prefix": "obut_Xr4pQ2aL",
"policies": [
{
"effect": "allow",
"permissionGroups": [
"responses.run",
"sessions.read",
"sessions.write"
],
"resources": ["openbot.org.{org}"]
}
],
"createdAt": "2026-10-20T09:00:00.000Z",
"expiresAt": "2027-01-18T09:00:00.000Z",
"lastUsedAt": null
},
"secret": "obut_Xr4pQ2aL..."
}

Jedes Secret beginnt mit obut_. So erkennt man ein geleaktes Token leicht. Der prefix sind die ersten 13 Zeichen. Damit kannst du deine Tokens unterscheiden.

Tokens auflisten

Terminal window
curl -b cookies.txt https://api.example.com/v1/user/tokens

Die Antwort ist { "items": [ ... ] }, das älteste zuerst. Die Liste enthält nie Secrets. lastUsedAt ändert sich höchstens einmal pro Minute. Abgelaufene Tokens bleiben in der Liste, bis du sie widerrufst.

Ein Token widerrufen

Terminal window
curl -X DELETE -b cookies.txt \
-H "Origin: https://api.example.com" \
https://api.example.com/v1/user/tokens/5f0c2a8e-7d1b-4c3e-9a55-2b6f1e8d4c10

OpenBot antwortet mit 204 und löscht das Token. Das Token funktioniert sofort nicht mehr.

Ein Token prüfen

GET /v1/tokens/verify zeigt, wer der Aufrufer ist. Bei einem Token zeigt es auch das Token und seine Policies. Jeder Aufrufer kann es nutzen.

{
"caller": {
"kind": "user_token",
"userId": "u_123",
"organizationId": "org_8f3a",
"tokenId": "5f0c2a8e-7d1b-4c3e-9a55-2b6f1e8d4c10"
},
"token": { "id": "5f0c2a8e-7d1b-4c3e-9a55-2b6f1e8d4c10", "name": "CI bot" }
}

Mit dem Session-Cookie ist caller.kind gleich member und token ist null.

Grenzen und Fehler

Status Fehler Wann
400 TokenPolicyInvalid Eine Policy nennt eine Ressource außerhalb deiner Organisation oder openbot.platform.
401 AuthenticationRequired Kein gültiges Cookie oder Token.
403 PermissionDenied Der Aufrufer hat tokens.read oder tokens.write nicht.
403 ForbiddenOrigin Ein Schreibzugriff mit Cookie ohne den genauen Header Origin.
404 TokenNotFound Du hast kein Token mit dieser ID.
409 TokenLimitReached Du hast schon 25 Tokens. Der Body enthält "limit": 25.
503 TokenStorageUnavailable OpenBot erreicht seine Datenbank nicht.

Ein Member kann 25 Tokens gleichzeitig haben. Abgelaufene Tokens zählen mit. Widerrufe also alte Tokens, um Platz zu schaffen.


Ein Token nutzen

Sende das Token im Header Authorization an jede Route unter /v1:

Terminal window
curl -H "Authorization: Bearer $OPENBOT_TOKEN" \
https://api.example.com/v1/sessions

Ein widerrufenes, abgelaufenes oder unbekanntes Token bekommt 401 mit AuthenticationRequired. Wenn OpenBot das Token nicht prüfen kann, antwortet es mit 503 und AuthenticationUnavailable.

Dein eigener Bereich

In der Organisation hat jedes Member seine eigenen Sessions, Apps und Verbindungen. Deine Tokens und dein Cookie sehen nur deine eigenen. Wenn du nach einer Session eines anderen Members fragst, antwortet OpenBot mit 404, als ob es sie nicht gäbe.


Rückkehrpfade

Manche Abläufe schicken den Browser nach einem Umweg zurück zu deinem Client. Du wählst den Ort mit returnTo.

Ein Rückkehrpfad muss ein Pfad auf demselben Origin sein. Er muss mit genau einem / beginnen. Er darf nicht auf /auth/*, /v1/* oder /development/* zeigen, weil diese Pfade OpenBot gehören. Der Standard ist /.

OpenBot hat keine Seiten. Dein Client muss diese Pfade also selbst bereitstellen. Zwei Abläufe fügen einen Query-Wert hinzu:

  • App-Autorisierung. Wenn eine App-Anmeldung zurückkommt und die Person angemeldet ist, beendet OpenBot den Ablauf. Der Browser geht zum Rückkehrpfad mit ?authorization=<flowId>. Dein Client kann das Ergebnis mit GET /v1/app-authorizations/<flowId> lesen. Wenn die Person nicht angemeldet ist, geht der Browser zu /?authorization=<flowId>. Dein Client meldet die Person mit POST /auth/sign-in an (siehe Anmelden), mit dieser Adresse als returnTo. Dann ruft er POST /v1/app-authorizations/<flowId>/complete auf, um den Ablauf zu beenden.
  • Entwickler-Tests. Eine Autorisierung für einen Entwickler-Test kehrt zu /?developerTest=<testId> zurück.