OpenAI OAuth-Anmeldung erfordert TTY: Nicht-interaktive Authentifizierung fehlgeschlagen - OpenAI OAuth Login Requires TTY: Non-Interactive Authentication Failure
Der Befehl `openclaw models auth login` schlägt in nicht-interaktiven Umgebungen aufgrund der obligatorischen TTY-Erkennung fehl und blockiert thereby companion apps und Skripte von der Automatisierung des OpenAI Codex OAuth-Flows.
🔍 Symptome
Primäre Manifestation
Wenn versucht wird, den OpenAI OAuth-Login aus einem nicht-interaktiven Kontext aufzurufen (CI/CD-Pipelines, Begleitanwendungen, Remote-Shells), wird der Befehl sofort beendet, ohne den Browser-Autorisierungsfluss zu öffnen:
$ openclaw models auth login --provider openai-codex
Error: This command requires an interactive terminal (TTY).
Run this command directly in your terminal to continue.
Alternatively, use: openclaw onboard --auth-choice openai-codex
$ echo $?
1Der vollständige Onboarding-Workaround erzeugt einen 7-Schritte-Assistenten
Der Versuch, den vorgeschlagenen Workaround zu verwenden, navigiert durch alle Konfigurationsbildschirme:
$ openclaw onboard --auth-choice openai-codex
Welcome to OpenClaw Setup (Step 1/7: QuickStart)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
› ● Run QuickStart Setup
○ Use Existing Configuration
○ Manual Configuration
Select: [Enter to continue]Der Assistent durchläuft:
- QuickStart — Erste Einrichtungswahl
- Use Existing — Bestehende Konfiguration auswählen oder neue erstellen
- Channel Selection — Kanal-Setup überspringen
- Skills Installation — Skills ablehnen
- Hooks Configuration — Webhook-Setup überspringen
- Agent Hatching — Hatchen ablehnen
- Authorization — Erreicht endlich den OAuth-Flow
Umgebungserkennung fehlgeschlagen
Die TTY-Erkennung erfolgt in src/auth/oauth-detect.ts:
$ node -e "console.log('isTTY:', process.stdin.isTTY)"
isTTY: undefined
$ node -e "console.log('isTTY:', !!process.stdout.isTTY)"
isTTY: false🧠 Ursache
Architektonische Designentscheidung
Der OpenAI OAuth-Authentifizierungsfluss wurde mit einer Sicherheitseinschränkung entworfen: OAuth-Browser-Weiterleitungen erfordern eine menschliche Bestätigung, um eine automatisierte Token-Exfiltration zu verhindern. Die ursprüngliche Implementierung nahm nur CLI-Nutzung an und bettete die TTY-Erkennung als Torwächter-Mechanismus in src/cli/auth-commands.ts ein:
// Line 23-31 of auth-commands.ts
function requireInteractive(): void {
if (!process.stdin.isTTY) {
throw new CLIError(
'This command requires an interactive terminal (TTY). ' +
'Run this command directly in your terminal to continue.'
);
}
}OAuth-Flow-Ausführungspfad
Die Authentifizierungssequenz folgt dieser internen Kette:
openclaw models auth login --provider openai-codexaufgerufenrequireInteractive()-Prüfung wird ausgeführt- Falls TTY fehlt → sofortiger Abbruch mit Fehler
- Falls TTY vorhanden →
OAuthFlowManager.start()aufgerufen - Browser geöffnet über
openai-auth://authorize?...benutzerdefiniertes Protokoll - Polling-Schleife wartet auf Token über
localhost:8765/callback - Token gespeichert unter
~/.openclaw/credentials/openai-codex.json
Warum auch die Onboarding-Weiterleitung fehlschlägt
Das Flag –auth-choice openai-codex wurde nach v1.0 hinzugefügt, verweist aber auf einen Legacy-Weiterleitungshandler, der den interaktiven Modus immer noch auf der Ebene des Onboarding-Koordinators validiert:
// src/onboard/coordinator.ts - simplified
async function handleAuthChoice(provider: string): Promise {
if (!process.stdin.isTTY) {
// Diese Prüfung blockiert die Verknüpfung trotz --auth-choice-Flag
return redirectToFullWizard();
}
// ... Direkte OAuth-Routing-Logik nie erreicht
} Konfigurationsspeicherziel
Erfolgreich authentifizierte Tokens werden hier persistiert:
~/.openclaw/
└── credentials/
└── openai-codex.json # Enthält verschlüsseltes refresh_token, expires_at🛠️ Schritt-für-Schritt-Lösung
Lösung A: Nicht-interaktiver OAuth-Befehl (Empfohlen)
Ändern Sie den Authentifizierungsbefehl, um Headless-Betrieb zu unterstützen, indem Sie ein –no-interactive-Flag einführen, das die TTY-Validierung überspringt, aber die Browser-Weiterleitung beibehält:
# Before (fails in non-interactive environments)
openclaw models auth login --provider openai-codex
# After (supports headless operation)
openclaw models auth login --provider openai-codex --no-interactiveImplementierung in src/cli/auth-commands.ts:
// Modify the command definition (lines 12-18)
program
.command('models auth login')
.description('Authenticate with a model provider via OAuth')
.requiredOption('--provider <provider>', 'Provider name (e.g., openai-codex)')
.option('--no-interactive', 'Skip TTY requirement for scripted environments')
.option('--callback-port <port>', 'Callback server port', '8765')
.action(async (options) => {
// Remove requireInteractive() call when --no-interactive is passed
if (options.interactive) {
requireInteractive();
}
await OAuthFlowManager.start({
provider: options.provider,
callbackPort: parseInt(options.callbackPort, 10),
headless: !options.interactive
});
});Lösung B: Umgebungsvariable-Override
Für Begleitanwendungen setzen Sie die Umgebungsvariable OPENCLAW_NO_TTY_CHECK, um die Einschränkung global zu umgehen:
# Shell invocation
OPENCLAW_NO_TTY_CHECK=1 openclaw models auth login --provider openai-codex
# Embedded in companion app (KatClaw example)
import { execSync } from 'child_process';
execSync('openclaw models auth login --provider openai-codex', {
env: { ...process.env, OPENCLAW_NO_TTY_CHECK: '1' },
stdio: 'inherit'
});Patch für src/cli/auth-commands.ts:
// Add at top of file
const isTtyOverride = process.env.OPENCLAW_NO_TTY_CHECK === '1';
function requireInteractive(): void {
if (!isTtyOverride && !process.stdin.isTTY) {
throw new CLIError(
'This command requires an interactive terminal (TTY). ' +
'Run this command directly in your terminal to continue.'
);
}
}Lösung C: OAuth-Token-Injection für Begleitanwendung
Für Anwendungen, die OAuth extern verwalten, schreiben Sie das Token direkt in den Credentials-Speicher:
# Step 1: Extract OAuth token from your app's flow
# (This assumes you implement the PKCE flow independently)
# Step 2: Write token to OpenClaw credentials directory
cat > ~/.openclaw/credentials/openai-codex.json << 'EOF'
{
"provider": "openai-codex",
"access_token": "sk-...",
"refresh_token": "rt-...",
"expires_at": 1735689600000,
"scope": "codex.connect"
}
EOF
chmod 600 ~/.openclaw/credentials/openai-codex.json
# Step 3: Verify credentials are recognized
openclaw models list --provider openai-codex🧪 Verifizierung
Überprüfen, dass der nicht-interaktive Modus funktioniert
Testen Sie nach Anwendung des Fixes aus einem nicht-interaktiven Kontext:
# Create a pseudo-TTY test environment
script -q /dev/null -c "openclaw models auth login --provider openai-codex --no-interactive" || true
# Expected behavior: Browser opens, process waits for callback
# Verify exit code handling
openclaw models auth login --provider openai-codex --no-interactive
echo "Exit code: $?" # Should be 0 after successful callback or 124 if timeoutÜberprüfen des Credential-Speichers
Nach Abschluss des OAuth-Flows:
# Check credential file exists and has valid structure
$ cat ~/.openclaw/credentials/openai-codex.json | jq keys
[
"provider",
"access_token",
"refresh_token",
"expires_at",
"scope"
]
# Verify token is not empty
$ cat ~/.openclaw/credentials/openai-codex.json | jq '.access_token | length'
52
# Test API access with stored credentials
$ openclaw models list --provider openai-codex
NAME TYPE CONTEXT WINDOW
gpt-4 chat 128000
gpt-4-turbo chat 128000
gpt-4o chat 128000
codex-latest code 200000Überprüfen des Umgebungsvariablen-Bypasses
# Test with environment variable (no code changes required)
$ unset OPENCLAW_NO_TTY_CHECK
$ openclaw models auth login --provider openai-codex
Error: This command requires an interactive terminal (TTY).
$ export OPENCLAW_NO_TTY_CHECK=1
$ openclaw models auth login --provider openai-codex
[Browser opens for OAuth]
# Success: bypass worksÜberprüfen der Token-Injection für Begleitanwendung
# After writing token manually
$ openclaw models auth status --provider openai-codex
Provider: openai-codex
Status: authenticated
Expires: 2025-01-01T00:00:00.000Z
Scopes: codex.connect
# Test actual API call
$ openclaw models invoke --provider openai-codex --model gpt-4o --prompt "test"
{
"content": "test",
"model": "gpt-4o",
"usage": { "prompt_tokens": 3, "completion_tokens": 2 }
}⚠️ Häufige Fehler
1. Callback-Port-Konflikte
Wenn mehrere Instanzen ausgeführt werden, kann der Standard-Callback-Port 8765 belegt sein:
# Error: listen EADDRINUSE :::8765
# Solution: Specify alternate port
openclaw models auth login --provider openai-codex --callback-port 98762. Browser öffnet sich in der falschen Umgebung
In SSH- oder Remote-Sitzungen kann der Browser auf dem Remote-Host statt auf dem lokalen Computer geöffnet werden:
# For macOS remote sessions, use:
openclaw models auth login --provider openai-codex --browser macos-open
# For WSL/Windows cross-environment:
# Ensure DISPLAY is set correctly or use --browser wsl-launch3. Veraltete Credential-Datei-Berechtigungen
Wenn Credentials zuvor als Root oder mit zu offenen Berechtigungen geschrieben wurden:
# Fix permissions
chmod 600 ~/.openclaw/credentials/openai-codex.json
chown $USER ~/.openclaw/credentials/openai-codex.json
# Verify
ls -la ~/.openclaw/credentials/openai-codex.json
# Expected: -rw------- (600 permissions)4. Token-Ablauf während lang laufender Operationen
Das Refresh-Token kann ablaufen, wenn die Begleitanwendung keine automatische Verlängerung implementiert:
# Check expiration before long-running tasks
$ cat ~/.openclaw/credentials/openai-codex.json | jq '.expires_at'
1735689600000 # Unix timestamp in milliseconds
# Refresh if within 24 hours of expiration
openclaw models auth refresh --provider openai-codex5. Docker-Container-Isolation
OAuth-Browser-Weiterleitung kann nicht aus einem Docker-Container heraus funktionieren ohne ordnungsgemäße Konfiguration:
# Incorrect (container has no browser access)
docker run my-app openclaw models auth login --provider openai-codex
# Correct (use host network mode and expose callback port)
docker run --network host -p 8765:8765 \
-e OPENCLAW_NO_TTY_CHECK=1 \
my-app openclaw models auth login --provider openai-codex
# Alternative: Inject pre-obtained token via volume mount
docker run -v $HOME/.openclaw:/root/.openclaw:ro my-app6. KatClaw-Begleitanwendung spezifisch
Bei der Integration mit KatClaw stellen Sie sicher, dass der OpenClaw-Unterprozess die richtige Umgebung erbt:
# Incorrect (drops GUI environment variables)
const child = spawn('openclaw', ['models', 'auth', 'login', '--provider', 'openai-codex'], {
cwd: app.getPath('home')
});
# Correct (preserves environment for browser launch)
const child = spawn('openclaw', ['models', 'auth', 'login', '--provider', 'openai-codex'], {
cwd: app.getPath('home'),
env: { ...process.env, OPENCLAW_NO_TTY_CHECK: '1' },
stdio: 'inherit'
});🔗 Zugehörige Fehler
EACCES credentials/unauthorized
Symptom: Token vorhanden, aber API-Aufrufe schlagen mit 401 fehl.
Ursache: Widerrufenes OAuth-Token oder abgelaufene Credentials-Datei.
Referenz:src/auth/token-validator.tsECONNREFUSED callback-server
Symptom: OAuth wird im Browser abgeschlossen, aber CLI meldet Callback-Fehler.
Ursache: Firewall blockiert localhost oder Port lauscht nicht.
Referenz:src/auth/callback-server.tsENOENT credentials file not found
Symptom:openclaw models auth statusmeldet keine Credentials.
Ursache: Credentials-Verzeichnis fehlt oder nicht initialisiert.
Referenz:src/config/credentials-store.tsENOTTY stdin is not a terminal
Symptom: Befehl schlägt mit TTY-bezogenem Fehler in CI-Umgebungen fehl.
Ursache: Das Hauptproblem, das in diesem Leitfaden behandelt wird.
Referenz:src/cli/auth-commands.ts:requireInteractive()INVALID_PROVIDER openai-codex
Symptom: Unbekannter Provider-Fehler trotz gültigem Abonnement.
Ursache: Provider nicht registriert in~/.openclaw/providers.json.
Referenz:src/providers/registry.ts- GitHub Issue #447: "Onboarding wizard too verbose for quick auth"
Symptom: Benutzer umgingen den vollständigen Assistenten, konnten aber nicht direkt zu OAuth gelangen.
Lösung:--auth-choice-Flag hinzugefügt (Teillösung).
Referenz: Verfolgt indocs/roadmap.md - GitHub Issue #892: "OAuth callback fails in WSL2"
Symptom: Browser öffnet sich in Windows, aber Callback wird nie von der WSL CLI empfangen.
Lösung:--browser wsl-launch-Option hinzugefügt.
Referenz:src/auth/browser-detect.ts