Skip to content

OAuth renewal doesn't update auth-profiles.provisioned.json, causing recovery loops #38336

Description

@dfrysinger

Summary

When OAuth tokens are renewed via openclaw onboard, the token is saved to auth-profiles.json (live copy) but NOT to auth-profiles.provisioned.json (golden copy). This causes safe-mode recovery to repeatedly fail because it reads from the golden copy.

The Architecture

~/.openclaw/agents/main/agent/auth-profiles.json            # Live copy (gateway reads/writes)
~/.openclaw/agents/main/agent/auth-profiles.provisioned.json # Golden copy (recovery reads)

From build-full-config.sh (lines 275-279):

# Golden copy — never modified by gateway, survives shutdown persistence clobber.
# Safe mode recovery reads from this to find OAuth tokens that may have been
# dropped from the live copy during gateway restart cycles.
# NOTE: This is static after provisioning. If credentials are rotated at runtime
# (e.g., OAuth token refresh), re-run build-full-config.sh to update the golden copy.

From safe-mode-recovery.sh (lines 192-200):

# Find auth-profiles.json — prefer golden provisioned copy (survives gateway
# SIGTERM persistence clobber), fall back to live copy if golden doesn't exist.
for path in \
  "$home/.openclaw/agents/main/agent/auth-profiles.provisioned.json" \
  "$home/.openclaw/agents/main/agent/auth-profiles.json" \
  ...

The Problem

  1. User runs openclaw onboard --auth-choice openai-codex
  2. OAuth flow completes, token saved to auth-profiles.json
  3. auth-profiles.provisioned.json is NOT updated ❌
  4. Later, something triggers safe-mode recovery
  5. Recovery reads from .provisioned.json (stale token)
  6. Recovery thinks OAuth is broken → stays in safe mode
  7. User re-runs OAuth → same loop repeats

Current Workaround

After OAuth renewal, manually copy live → golden:

cp ~/.openclaw/agents/main/agent/auth-profiles.json \
   ~/.openclaw/agents/main/agent/auth-profiles.provisioned.json

Proposed Fix

Option A: Update openclaw onboard to sync golden copy

When openclaw onboard successfully saves OAuth credentials, also update the provisioned copy:

// After writing auth-profiles.json
const provisionedPath = path.join(agentDir, 'auth-profiles.provisioned.json');
if (fs.existsSync(provisionedPath)) {
  fs.copyFileSync(authProfilesPath, provisionedPath);
}

Option B: Document the manual step

Add to safe-mode agent TOOLS.md and main docs:

  • Explain the two-file architecture
  • Document the manual copy step after OAuth renewal

Context

This was discovered during a multi-hour safe-mode debugging session where:

  • Discord tokens were fixed in both habitat-parsed.env and openclaw.full.json
  • OpenAI OAuth was renewed multiple times via openclaw onboard
  • Recovery kept reverting to safe mode because .provisioned.json had stale token

Related issue: #37659 (other safe-mode documentation gaps)

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleMarked as stale due to inactivity

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions