Zum Artikel springen
HB CodeDocsApp herunterladen

HandbuchRelay & Konten

Konten, Authentifizierung und Regionen

Die Auth0-PKCE-Übergabe über Redis, das HB-Code-JWT und seine Erneuerung, was ein Regionswechsel ungültig macht, wie ein Telefon Codex-Profile und Claude-Konten liest und wechselt, und welche Daten Ihren Computer verlassen.

Gegen den Quellcode geprüft am 5. Oktober 2026

Auf dieser Seite

Wie die native Anmeldung zur App zurückkehrt

Der Browser liefert den Code an den regionalen Server, und nur die abfragende App kann ihn einlösen
Der Browser liefert den Code an den regionalen Server, und nur die abfragende App kann ihn einlösenDie Zeit läuft von links nach rechts. Die App öffnet den Browser bei initiate-login des regionalen Servers, das einen State-Schlüssel in Redis speichert und zu Auth0 weiterleitet. Die App beginnt sofort mit dem Abfragen und erhält 204, während die Anmeldung läuft. Auth0 schickt den Browser mit dem Code zum Callback. Der Callback verbraucht den State-Schlüssel und parkt den Code unter der Polling-ID der App, sodass ein wiederholter Callback 401 erhält. Eine Abfrage liest den geparkten Code, ohne ihn zu verbrauchen, sodass nach einer verlorenen Antwort die nächste Abfrage denselben Code erhält. Die App löst den Code einmal mit ihrem Verifier bei Auth0 ein und ruft dann finalize-login auf, das das HB-Code-JWT zurückgibt und den Poll-Schlüssel löscht. Nichts läuft vom Browser zur App.
AppDesktop oder Telefon
Browser
Auth0
Regionale APISchlüssel in Redis
State-Schlüssel
Poll-Schlüssel
Anmeldung
pid · csrf
Code · csrf, SET NX
fragt von Anfang an ab: 204, bis der Code geparkt ist
öffnet initiate-login mit Challenge, pid, csrf
Antwort verloren
Callback mit dem Code
verbraucht
Code + Verifier, einmal
finalize-login: JWT zurück
gelöscht
wiederholter Callback: 401
Die App gibt nach höchstens 60 Abfragen auf, nach etwa 2 bis 2,5 Minuten. Ein später geparkter Code verfällt nach 30 Minuten ungenutzt.
Nichts läuft vom Browser zur App, und der Verifier verlässt die App nur in Richtung Auth0.
  • State-Schlüsselauth0:state:{state}

    Von initiate-login mit Polling-ID und CSRF-Token geschrieben und vom Callback gelöscht, sobald er den Code parkt. Ein wiederholter Callback findet nichts und erhält 401.

  • Poll-Schlüsselauth0:poll:{pid} · SET NX

    Abfragen lesen ihn, ohne ihn zu verbrauchen, sodass nach einer verlorenen Antwort die nächste Abfrage denselben Code erhält. finalize-login löscht ihn nach dem Ausstellen des JWT, und beide Schlüssel laufen nach 30 Minuten ab.

  • AbfragenGET /auth0/poll-status

    Telefone fragen alle 2 Sekunden ab, bis zu 60-mal. Der Desktop fragt etwa eine Minute lang alle 2 Sekunden ab, danach alle 3, und hört nach 60 Abfragen oder 150 Sekunden auf.

  • Verifiercode_verifier

    Wird mit der Polling-ID erzeugt und im Arbeitsspeicher der App gehalten. Nur der Token-Endpunkt von Auth0 erhält ihn, einmal, sodass ein geparkter oder abgefangener Code ohne ihn nutzlos ist.

Die Auth0-Tokens laufen einmal durch Ihr Gerät, und die Agent-Anmeldungen verlassen den Desktop nie
Die Auth0-Tokens laufen einmal durch Ihr Gerät, und die Agent-Anmeldungen verlassen den Desktop nieBei der Anmeldung tauscht die App den Code bei Auth0 gegen ein Zugriffstoken und ein Refresh-Token ein, sendet beide einmal an finalize-login und behält keines davon. Der regionale Server speichert das Refresh-Token verschlüsselt und tauscht es selbst bei Auth0 ein, sobald ein Gerät erneuert. Jedes Gerät behält sein eigenes HB-Code-JWT, 7 Tage gültig und bis 24 Stunden nach dem Ablauf erneuerbar. Die ChatGPT-Anmeldung und die Claude-Anmeldung bleiben auf dem Desktop. Codex nutzt die erste für jeden Codex-Turn mit OpenAI, und Claude nutzt die zweite für jeden Claude-Turn mit Anthropic. Über das Relay gehen nur Name, E-Mail, Plan und Nutzungslimits von beiden an Telefone.
Ihre Geräte
Regionaler Server
Auth0
Auth0-Tokens: einmal genutzt, nicht behalten
HB-Code-JWTSchlüsselbund oder Keystore, je Gerät
Auth0-Refresh-TokenTabelle users, AES-256-GCM
Zugriffs- und Refresh-Token, einmal
Refresh-Token gegen neue Tokens, je Erneuerung
finalize-login, einmal
neues JWT pro Gerät
Erneuerung mit dem JWT
Lebensdauer des HB-Code-JWT
7 Tage gültig
24 h Gnadenfrist: Erneuerung geht noch
Nur Desktop: Agent-Anmeldungen
ChatGPT-AnmeldungAuth-Home des Codex-Profils
Claude-AnmeldungClaudes eigener Speicher
Relaygibt sie an Telefone weiter, ohne Anmeldung
Name, E-Mail, Plan, Limits
OpenAI
Anthropic
jeder Codex-Turn
jeder Claude-Turn
  • Zugriffstokenfinalize-login · auth0_id_token

    Die App erhält es aus ihrem eigenen Code-Austausch und sendet es einmal an finalize-login, in einem Feld, das noch auth0_id_token heißt. Der Server prüft es, holt damit userinfo und speichert es nirgends.

  • Refresh-Tokenusers.auth0_refresh_token

    Läuft einmal durch die App. Der Server speichert es verschlüsselt, tauscht es mit seinen eigenen Client-Zugangsdaten bei Auth0 ein und behält das rotierte Token, auch wenn die neuen Tokens danach die Prüfung nicht bestehen.

  • HB-Code-JWTJWT_ACCESS_TOKEN_DURATION_DAYS = 7

    Pro Gerät mit einem device_id-Claim ausgestellt. Bis zu 24 Stunden nach dem Ablauf tauscht refresh-app-token es noch gegen ein neues. Danach ist eine neue Anmeldung nötig.

  • ChatGPT-Anmeldungcodex --auth-home

    Entsteht durch die eigene Anmeldung des Codex-Kindprozesses und liegt im Auth-Home des Desktop-Profils. Telefone erhalten über das Relay Name, E-Mail, Plan und Nutzungslimits des Profils, nie die Anmeldung selbst.

  • Claude-Anmeldungclaude auth login --claudeai

    Entsteht durch den eigenen Anmeldebefehl von Claude, den der Desktop für einen Kontoordner ausführt. Der Desktop liest das Token nie. Telefone erhalten über das Relay E-Mail, Organisation, Plan und Nutzungsfenster des Kontos.

HTTP-EinstiegspunktZweck
GET /auth/auth0/initiate-loginAccount-Login initiieren.
GET /auth/auth0/callbackAuth0 leitet den Browser hierher. Den Code parken und den Browser auf eine Bestätigungsseite schicken.
GET /auth0/poll-statusNicht konsumierende Abfrage; 204 mit Cache-Control: no-store, bis der Code geparkt ist.
POST /auth0/finalize-loginAuth0-Token und Client-ID prüfen, eine verifizierte E-Mail verlangen, das HB-Code-JWT ausstellen, das Erstanmeldeguthaben gewähren und dann den Poll-Schlüssel löschen, wenn die Anfrage dessen Polling-ID und CSRF-Token enthält.
POST /api/auth0/refresh-app-tokenDas HB-Code-App-Token erneuern. Die einzige Route, die ein abgelaufenes Token akzeptiert.

Das Verbrauchen des State-Schlüssels und das Löschen des Poll-Schlüssels laufen jeweils als ein Lua-Skript in Redis. Der Speicher ist Redis statt Arbeitsspeicher, weil jeder API-Prozess der Region ihn teilt.

Das HB-Code-JWT ist HS256 mit gemeinsamem Geheimnis, Aussteller hbcode, Zielgruppe hbcode-api und Scope read write rpc. Seine jti wird bei jeder Anfrage und erneut beim WebSocket-Upgrade gegen eine Sperrtabelle geprüft, sein device_id-Claim wird mit dem X-Device-ID-Header verglichen, und es lebt standardmäßig 7 Tage. Die Erneuerungsroute akzeptiert ein Token noch bis zu 24 Stunden nach seinem Ablauf, wobei Aussteller, Zielgruppe, Gerätebindung, Scopes und Sperrung weiter durchgesetzt werden, läuft in einer pro Benutzer serialisierten Transaktion und verweigert ein neues Token, wenn Auth0-Subject oder E-Mail nicht mehr zum gespeicherten Benutzer passen. Das WebSocket-Upgrade erfasst vor seiner Sperrprüfung eine Registrierungssperre pro Benutzer, sodass eine Abmeldung, die zwischen HTTP-Prüfung und Relay-Registrierung abschließt, die Registrierung ungültig macht.

Das optionale Server-Client-Credential-Paar des Servers wird für den serverseitigen Auth0-Refresh-Austausch benötigt. Konfigurieren Sie die Auth0-Domäne, die native Client-ID, die Audience und die Callback-Einstellungen der nativen App gemeinsam. Die ausgewählte API-Region und die iOS-authServerURL sind unterschiedliche Konfigurationspfade, prüfen Sie also beide beim Einrichten einer lokalen Umgebung.

Was ein Regionswechsel oder eine Abmeldung ungültig macht

Ein Regionswechsel oder eine Abmeldung beendet den vorherigen Versuch und löscht seine Zugangsdaten. Ein spätes Ergebnis eines alten Versuchs kann kein Konto wiederherstellen, weil jedes Ergebnis an den Versuch und den Ursprung gebunden ist, die es gestartet haben.

Anmeldung, Abmeldung, Token-Erneuerung und Session-Abgleich auf dem Desktop teilen eine Mutationssperre, und die Abstimmung verwirft Ergebnisse, wenn sich Token oder Ursprung während einer Anfrage geändert haben. Callback-Wiederholung wird abgewiesen, und die Übergabebestätigung ist idempotent.

Agent-Konten vom Telefon aus

Codex-Profile und Claude-Konten liegen auf dem Desktop. Ein Telefon liest sie und wählt das aktive über sechs Relay-Methoden im Namensraum system. Vier Methoden lesen. Zwei Methoden wechseln, und beide sind Mutationen, die einen idempotencyKey brauchen.

MethodeParameter und Ergebnis
system.codexAuthProfilesLesen, keine Parameter. Gibt profiles zurück. Jeder Eintrag hat profileId, label, authMode, accountId, email, name, planType, workspaceName, workspaceKind, isAuthenticated, isActiveAgentChat, canDelete, ownedSessionLinkCount und errorMessage.
system.activateCodexAuthProfileMutation, Parameter profileId. Gibt dieselbe profiles-Liste zurück, nach dem Wechsel gelesen.
system.codexUsageLimitsLesen, keine Parameter. Gibt die Limits des aktiven Codex-Profils zurück: primary und secondary, jeweils mit usedPercent, windowMinutes und resetsAt, dazu credits, planType und rateLimitReachedType.
system.claudeAccountsLesen, keine Parameter. Gibt accounts zurück. Jeder Eintrag hat accountId, isDefault, isActive, signedIn, email, organization, planType, usageWindows und errorMessage. Ein Nutzungsfenster hat kind (session oder weekly), model, usedPercent und resetsAt.
system.activateClaudeAccountMutation, Parameter accountId. Gibt dieselbe accounts-Liste zurück, nach dem Wechsel gelesen.
system.agentUsageHistoryLesen, Parameter agent mit dem Wert codex oder claude. Gibt agent, recordingSince, weeklySamples (sampledAt, usedPercent, resetsAt), dailyTokens und tokenSummary zurück.

Die zwei Wechselmethoden nehmen nur ihre eine ID an. Ein unbekanntes Feld, ein snake_case-Feld oder eine leere ID ist ein invalid-params-Fehler. system.agentUsageHistory lehnt jeden agent-Wert außer codex und claude ab.

Ein Wechsel vom Telefon ändert eine Einstellung, und der schon laufende Turn behält sein Konto
Ein Wechsel vom Telefon ändert eine Einstellung, und der schon laufende Turn behält sein KontoDie Zeit läuft von links nach rechts in vier Bahnen: Telefon, Relay, Desktop und der Agent-Host von Claude. Ein Claude-Turn läuft mit Konto A. Das Telefon sendet system.activateClaudeAccount für Konto B mit dem Schlüssel k1 über das Relay. Der Desktop schreibt die Einstellung für das aktive Konto und antwortet mit der Kontoliste, und diese Antwort geht auf dem Weg zum Telefon verloren. Das Telefon sendet denselben Aufruf mit demselben Schlüssel erneut. Der Desktop wechselt kein zweites Mal und gibt die gespeicherte Antwort zurück, in der B aktiv ist. Der Host des laufenden Turns behält Konto A, bis der Turn endet. Der nächste Turn startet einen neuen Host im Ordner von Konto B.
Telefon
Relayprüft den Schlüssel
Desktopbesitzt die Einstellung
Claude-Hosteiner pro Turn
laufender Turn: Konto A
nächster Turn: Konto B
Konto B aktivieren, Schlüssel k1
schreibt die Einstellung, stoppt nichts
Antwort verloren
gleicher Aufruf, Schlüssel k1
kein zweiter Wechsel
gespeicherte Antwort: B ist aktiv
neuer Host im Ordner von B
Das Telefon sendet nur eine Konto-ID. Keine Relay-Methode startet oder überträgt eine Anmeldung.
Codex arbeitet genauso: system.activateCodexAuthProfile schreibt agent.chat.codex_profile_id, und kein Codex-Kindprozess stoppt.
  • Wechselaufrufsystem.activateClaudeAccount · system.activateCodexAuthProfile

    Die Parameter sind eine ID, accountId oder profileId. Beide Methoden sind Mutationen. Das Relay lehnt sie ohne idempotencyKey mit dem Fehler -32026 ab.

  • Einstellungagent.chat.claude_account_id · agent.chat.codex_profile_id

    Der Wechsel ist ein Schreibvorgang in den Einstellungen auf dem Desktop. Er stoppt keinen Prozess. Der Desktop sendet danach agent-accounts-changed an sein eigenes Fenster.

  • Gespeicherte AntwortidempotencyKey

    Der Desktop bewahrt die fertige Antwort unter dem Schlüssel auf. Eine Wiederholung mit demselben Schlüssel und denselben Parametern erhält sie zurück, daher kann eine verlorene Antwort keinen zweiten Wechsel auslösen.

  • Nächster TurnCLAUDE_CONFIG_DIR

    Ein Claude-Turn liest das aktive Konto einmal, wenn er startet, und startet seinen Host mit dem Ordner dieses Kontos. Auch ein Codex-Wechsel stoppt keinen Kindprozess. Ein laufender Codex-Turn behält sein Profil, und der nächste Codex-Turn meldet sich mit dem aktiven Profil an.

Ein Wechsel ist ein Schreibvorgang in den Einstellungen. Er stoppt keinen Prozess und ändert nur, welche Anmeldung der nächste Turn nutzt. Der Session-Verlauf bleibt, wo er ist.

SchrittCodexClaude
PrüfenNimmt die Sperre für den Profil-Lebenszyklus und prüft, dass das Profil existiert.Sucht den Kontoordner. Ein unbekanntes Konto ist ein Fehler.
SchreibenSetzt agent.chat.codex_profile_id.Setzt agent.chat.claude_account_id. Das Standardkonto hat keinen eigenen Ordner, daher löscht der Wechsel zu ihm die Einstellung. Der Wechsel leert außerdem den zwischengespeicherten Claude-Modellkatalog.
Laufender TurnBehält das Profilpaar, mit dem er begonnen hat. Eine Steuernachricht geht an denselben Codex-Kindprozess.Behält seinen Host und seinen Kontoordner, bis der Turn endet.
Nächster Turn einer bestehenden SessionMeldet sich mit dem Profil an, das aktiv ist, wenn der Turn angenommen wird. Der Session-Verlauf bleibt in dem Profil, das ihn speichert. Ein Turn wird abgelehnt, wenn das aktive Profil nicht angemeldet ist.Liest die Einstellung einmal, wenn er startet, und läuft mit dem aktiven Konto. Jedes Konto liest dieselben Sessions und setzt sie fort.

Nach dem Schreiben sendet der Desktop das Ereignis agent-accounts-changed mit dem Agentennamen an sein eigenes Fenster. Die Seitenleiste und die Einstellungsseite lesen erneut. Ein fehlgeschlagenes Senden wird nur protokolliert, denn der Wechsel ist schon gespeichert, und das Desktop-Fenster holt ihn beim nächsten regelmäßigen Lesen nach.

Das Relay lehnt einen Wechsel ohne Schlüssel mit dem Fehler -32026 ab. Der Desktop speichert die fertige Antwort unter dem Schlüssel. Eine Wiederholung mit demselben Schlüssel und denselben Parametern erhält diese gespeicherte Antwort, und derselbe Schlüssel mit anderen Parametern ist ein Konflikt.

LesenAktualitätGrenze
Claude-KontenEine Messung pro Konto für 60 Sekunden. Eine Messung führt claude auth status --json mit 15 Sekunden Zeitlimit aus und liest für ein angemeldetes Konto einmal die Nutzung.Ein fehlgeschlagenes Lesen wird zu errorMessage an diesem Konto. Die Liste kommt trotzdem zurück. Ein beendeter Claude-Run verwirft die Messung seines Kontos.
Codex-NutzungslimitsEin zwischengespeicherter Wert für 60 Sekunden, gelesen über account/rateLimits/read am aktiven Profil.Der Cache hat keinen Profilschlüssel, und ein Wechsel leert ihn nicht. Bis zu 60 Sekunden nach einem Wechsel kann das Telefon die Limits des vorherigen Profils sehen.
Nutzungsverlauf, WochenwerteDer Desktop speichert jede frische Limit-Messung in der Tabelle agent_usage_samples. Er speichert nur die zwei Fenster über alle Modelle, das Fünf-Stunden-Fenster (session) und das Wochenfenster.Eine Messung, die die neueste innerhalb von 10 Minuten wiederholt, mit derselben Rücksetzzeit und weniger als 0,5 Prozentpunkten Änderung, wird übersprungen. Zeilen bleiben 35 Tage. Die Antwort enthält die letzten 14 Tage des aktiven Kontos, die ältesten zuerst.
Nutzungsverlauf, TokensNur Codex. dailyTokens und tokenSummary kommen aus account/usage/read. Der Desktop speichert eine Antwort 5 Minuten zwischen und verwirft sie, wenn das aktive Profil wechselt. dailyTokens enthält höchstens 30 Tage.Beide Felder sind null für Claude und für eine Codex-Anmeldung ohne Verlauf, etwa einen API-Schlüssel.

Lokale Ausführung nutzt trotzdem entfernte Dienste

Tools und Dateiänderungen laufen auf dem Desktop, und eine Modellanfrage sendet den Aufgabenkontext trotzdem an den Anbieter des Agenten der Session: OpenAI für Codex, Anthropic für Claude. Die mobile Steuerung sendet Anfragen und den zurückgegebenen Workspace-Inhalt über den regionalen Server. Das Diktat sendet eine Aufnahme an den von Ihnen konfigurierten Transkriptionsdienst, und die Gemini-Tools des Agenten senden Text oder Video unter Ihrem Schlüssel an Gemini.

„Desktop-eigen“ beschreibt also, wo Ausführung und Dateien leben. Es ist weder ein Offline-Modus noch ein Versprechen von Ende-zu-Ende-Verschlüsselung.