Skip to content

[Feature]: Allow disabling external-cli-sync for auth-profiles via config #70055

@keareyChia

Description

@keareyChia

Summary

openclaw currently hardcodes an auto-sync of external CLI credentials (MiniMax CLI, Codex CLI) into the per-agent auth-profile store. For users who have those CLIs installed locally but don't route them through openclaw, this produces noisy info logs on every command, with no config-level way to opt out. Requesting a first-class opt-out surface (config key, env var, or log downgrade).

Problem to solve

External CLI credential sync is unconditionally enabled at the API layer and is not reachable from user-facing configuration:

  1. Every command that loads the auth store prints an info-level "synced … credentials from external cli" message, even when the credential is not used by any agent's model selection.
  2. The message fires twice per command because loadAuthProfileStoreForAgent is invoked more than once per command lifecycle (init + model resolve).
  3. The synced credential is only written to in-memory runtimeStore — it never lands in auth-profiles.json, so the TTL-based "no-op if already synced" fast path can never engage across processes.
  4. The only way to skip the behavior today is to pass options.syncExternalCli = false at the JS API call site. There is no openclaw.json field, no environment variable, and no CLI flag exposed.

Effect: users who keep the upstream CLI installed but configure openclaw with their own <provider>:<scope> profiles see persistent log noise they cannot silence without patching node_modules.

Proposed solution

Any one of the following (listed by preference):

  1. Config opt-out in openclaw.json — add an auth.externalCliSync field:
    {
      "auth": {
        "externalCliSync": false
        // or object form for per-provider control:
        // "externalCliSync": { "providers": ["minimax-cli"] }   // only sync these
        // "externalCliSync": { "exclude":   ["codex-cli"] }     // sync all except these
      }
    }
    Read at the three call sites in loadAuthProfileStore, loadAuthProfileStoreForAgent, and the runtime-store clone path (around dist lines 878 / 914 / 948 / 1025).
  2. Environment variable — e.g. OPENCLAW_DISABLE_EXTERNAL_CLI_SYNC=1, or per-provider OPENCLAW_EXTERNAL_CLI_SYNC_PROVIDERS=minimax-cli.
  3. Log downgrade — demote the "synced … credentials from external cli" message to debug level when the synced credential is bit-for-bit identical to the previous sync within the TTL window (currently EXTERNAL_CLI_SYNC_TTL_MS = 15 min). This is the smallest change, but it does not help users who want to fully disable the behavior.

Alternatives considered

  • Delete ~/.codex/auth.json — not viable: the user actively uses Codex CLI outside openclaw, so removing the file breaks their upstream tool.
  • Set options.syncExternalCli = false at every call site locally — requires patching node_modules/openclaw/dist/store-*.js, which is lost on every upgrade.
  • Ignore the noise — acceptable short-term, but the message is in the info channel (not debug), so it leaks into user-facing CLI output regardless of log-level tuning at the user end.
  • Overlay an empty externalAuthProfiles override — (overlayExternalAuthProfiles appears in the same file) — the sync step runs before the overlay, so it cannot suppress the log.

Impact

  • User-visible — removes two lines of unsolicited info output from every command, improving CLI signal-to-noise.
  • Performance — avoids repeated reads of ~/.codex/auth.json + optional keychain lookups for users who have opted out (minor, but non-zero on cold start).
  • Backward compatibility — default-on preserves today's behavior; opt-out is purely additive.
  • Surface area — small. The existing shouldSyncExternalCliCredentials(options) helper already centralizes the gate; the change is to feed it from config/env in addition to the current options.syncExternalCli API arg.

Evidence/examples

Environment:

  • openclaw 2026.4.14
  • Windows 11, Node v24.9.0
  • Codex CLI installed and active at ~/.codex/ (auth.json present)
  • agents/<id>/agent/auth-profiles.json contains only user-declared profiles (e.g. deepseek:default, minimax:cn) — no openai-codex:default entry, confirming the sync never persists to disk

Reproduction:

$ openclaw models list --agent main
[agents/auth-profiles] synced openai-codex credentials from external cli
[agents/auth-profiles] synced openai-codex credentials from external cli
Model                                      Input      Ctx      Local Auth  Tags
minimax/MiniMax-M2.7                       text       200k     no    yes   default,configured,alias:chat-primary
deepseek/deepseek-chat                     text       128k     no    yes   fallback#1,configured,alias:chat-fallback

Relevant code references (in dist/store-*.js, identifiers stable across recent releases):

  • EXTERNAL_CLI_SYNC_PROVIDERS (hardcoded list of minimax-cli, codex-cli)
  • syncExternalCliCredentialsForProvider — emits log.info("synced ${provider} credentials from external cli", …) on every non-no-op path
  • shouldSyncExternalCliCredentials(options) — current gate, reads only options.syncExternalCli
  • loadAuthProfileStoreForAgent — invokes the sync on each call, and is itself invoked multiple times per command

Additional information

  • Happy to contribute a PR if a direction is confirmed — the change surface is small and localized.
  • If a maintainer prefers option 3 (log downgrade) as a near-term partial fix while option 1 is designed, I can send that as a standalone PR first.
  • The same reasoning applies symmetrically to the MiniMax CLI sync path; an opt-out should cover both providers uniformly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions