Skip to content

fix(agents): harden host-managed Claude CLI auth path#61276

Merged
vincentkoc merged 1 commit into
mainfrom
codex/test-anthropic-cli-auth-login
Apr 5, 2026
Merged

fix(agents): harden host-managed Claude CLI auth path#61276
vincentkoc merged 1 commit into
mainfrom
codex/test-anthropic-cli-auth-login

Conversation

@vincentkoc

Copy link
Copy Markdown
Member

Summary

  • Problem: OpenClaw's Anthropic Claude CLI backdoor path had a few security and config-drift holes around openclaw models auth login --provider anthropic --method cli --set-default, provider-owned auth patch application, inherited Claude Code env/config roots, and repo-local Claude settings flowing into non-interactive runs.
  • Why it matters: users relying on local claude auth login could end up with stale anthropic/* defaults/fallbacks, inherited parent routing/auth/config state, or repo-local .claude hooks/settings affecting host-managed CLI sessions.
  • What changed: tightened the native claude-cli path end-to-end: fixed migrated default-model replacement behavior, hardened provider-auth patch application, normalized malformed permission overrides, scrubbed inherited Claude env/config/plugin roots, forced --setting-sources user, and stabilized image hydration paths/extensions for prompt-cache reuse.
  • What did NOT change (scope boundary): this does not add audio/video CLI attachment support, does not introduce a second standalone Claude provider, and does not fix unrelated repo-wide build/tsgo failures already present on this tree.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause (if applicable)

  • Root cause: the Claude CLI migration/auth path was recursively merging provider-owned config patches, which preserved replaced model maps/fallbacks instead of letting the migration intentionally swap to claude-cli/*; the host-managed backend also trusted inherited Claude env/config state more than it should.
  • Missing detection / guardrail: there was not enough regression coverage for direct models auth login, non-interactive migration, malformed backend security flags, inherited Claude env/config/plugin roots, and repo-local setting-source isolation.
  • Contributing context (if known): upstream Claude Code still treats non-interactive sessions as trusted, still runs SessionStart hooks in --print, and still loads project/local settings unless --setting-sources constrains them.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file:
    • extensions/anthropic/cli-migration.test.ts
    • extensions/anthropic/cli-shared.test.ts
    • src/agents/cli-backends.test.ts
    • src/commands/models/auth.test.ts
    • src/commands/auth-choice.apply.plugin-provider.test.ts
    • src/plugins/provider-auth-choice-helpers.test.ts
    • src/gateway/gateway-cli-backend.live.test.ts
    • src/agents/cli-runner.helpers.test.ts
  • Scenario the test should lock in: Anthropic Claude CLI login/setup must replace migrated model maps and fallbacks, keep hardened backend defaults under config overrides, scrub inherited Claude env/config/plugin roots, force --setting-sources user, and keep stable image hydration paths/extensions.
  • Why this is the smallest reliable guardrail: the behavior spans direct command auth, provider-owned onboarding/setup, backend config normalization, and CLI runner image prep; helper-only coverage was not enough.
  • Existing test that already covers this (if any): src/agents/cli-auth-epoch.test.ts still covers the auth-epoch/session invalidation seam adjacent to this path.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • openclaw models auth login --provider anthropic --method cli --set-default now cleanly rewrites migrated defaults to claude-cli/* without leaving stale anthropic/* allowlist/fallback entries behind.
  • Anthropic Claude CLI onboarding/setup now keeps the same migrated fallback rewrite behavior in non-interactive paths.
  • Host-managed Claude CLI runs now scrub inherited Claude routing/auth/config/plugin env and force --setting-sources user, so repo-local .claude project/local settings and hooks do not silently flow into non-interactive OpenClaw sessions.
  • Claude CLI image hydration now reuses stable content-addressed paths and preserves shared media suffixes like HEIC instead of falling back to random temp dirs and .bin.

Diagram (if applicable)

Before:
openclaw auth/models auth -> anthropic cli migration
  -> recursive config patch merge + inherited Claude env/settings
  -> stale anthropic defaults/fallbacks and host-steered Claude runs

After:
openclaw auth/models auth -> provider-owned claude-cli migration replacement
  -> hardened host-managed claude-cli backend
  -> exact claude-cli defaults/fallbacks + scrubbed env/config roots + user-only setting sources

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (Yes)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (Yes)
  • Data access scope changed? (Yes)
  • If any Yes, explain risk + mitigation:
    • Claude CLI was already a local subprocess path, but this PR hardens it by clearing inherited Claude provider-routing/auth/config/plugin env, marking the subprocess as host-managed, and forcing --setting-sources user so repo-local .claude project/local settings and hooks do not silently affect non-interactive OpenClaw sessions.

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 25 / pnpm workspace
  • Model/provider: claude-cli/* via Anthropic CLI auth path
  • Integration/channel (if any): N/A
  • Relevant config (redacted):
agents:
  defaults:
    cliBackends:
      claude-cli:
        command: claude

Steps

  1. Run openclaw models auth login --provider anthropic --method cli --set-default with existing Anthropic defaults/fallbacks.
  2. Run provider-auth/onboarding flows that apply the same Claude CLI migration patch path.
  3. Resolve the claude-cli backend with default and custom override configs, then run image hydration prep for repeated prompts.

Expected

  • Migrated defaults/fallbacks switch cleanly to claude-cli/* without stale anthropic/* entries.
  • Host-managed claude-cli runs keep hardened env/config defaults and force --setting-sources user.
  • Repeated hydrated images reuse stable file paths and preserve HEIC/shared extensions.

Actual

  • Matches expected in the targeted test slices below.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios:
    • pnpm test:serial extensions/anthropic/cli-shared.test.ts src/agents/cli-backends.test.ts
    • pnpm test:serial extensions/anthropic/cli-migration.test.ts src/plugins/provider-auth-choice-helpers.test.ts extensions/anthropic/cli-shared.test.ts src/agents/cli-backends.test.ts src/commands/models/auth.test.ts src/commands/auth-choice.apply.plugin-provider.test.ts src/agents/cli-auth-epoch.test.ts src/gateway/gateway-cli-backend.live.test.ts src/agents/cli-runner.helpers.test.ts
  • Edge cases checked:
    • malformed bare --permission-mode
    • explicit unsafe --setting-sources overrides
    • missing local Claude CLI auth in non-interactive flow
    • command-only backend overrides
    • inherited Claude config/plugin env roots
    • stable repeated image path reuse and HEIC suffix preservation
  • What you did not verify:
    • src/agents/cli-runner.spawn.test.ts remains a local vitest hotspot and was not re-run to completion
    • audio/video CLI attachment support does not exist yet
    • repo-wide pnpm check / pnpm build are still red on unrelated issues already visible on this tree

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No public contract change; hardened runtime defaults only`)
  • Migration needed? (No)
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: a custom cliBackends.claude-cli.args override could rely on project/local Claude setting sources or malformed permission flags.
    • Mitigation: normalize backend args fail-safe to --setting-sources user and valid --permission-mode defaults.
  • Risk: local verification surfaces are partially blocked by unrelated repo-reds.
    • Mitigation: scoped serial tests for the touched path are green, and the unrelated pnpm build / pnpm check failures are called out explicitly below.

Known Unrelated Local Failures

  • pnpm build fails on this tree with unrelated unresolved import in src/agents/tool-display.ts for ../../apps/shared/OpenClawKit/Sources/OpenClawKit/Resources/tool-display.json.
  • pnpm check / pnpm tsgo also fail on unrelated repo-wide issues outside this change, including src/agents/pi-embedded-runner/google-prompt-cache*, src/docs/clawhub-plugin-docs.test.ts, src/gateway/reconnect-gating.test.ts, src/i18n/registry.test.ts, and src/ui-app-settings.agents-files-refresh.test.ts.

AI-assisted

  • AI-assisted with Codex.
  • Degree of testing: targeted serial verification on the touched Claude CLI auth/security path.

@openclaw-barnacle openclaw-barnacle Bot added gateway Gateway runtime commands Command implementations agents Agent runtime and tooling extensions: anthropic labels Apr 5, 2026
@vincentkoc vincentkoc self-assigned this Apr 5, 2026
@openclaw-barnacle openclaw-barnacle Bot added size: XL maintainer Maintainer-authored PR labels Apr 5, 2026
@vincentkoc vincentkoc force-pushed the codex/test-anthropic-cli-auth-login branch from d9c0d2e to 7eb2e04 Compare April 5, 2026 10:01
@vincentkoc vincentkoc marked this pull request as ready for review April 5, 2026 10:01
@vincentkoc vincentkoc force-pushed the codex/test-anthropic-cli-auth-login branch from 7eb2e04 to aeeca8d Compare April 5, 2026 10:02
@vincentkoc vincentkoc merged commit 3b84884 into main Apr 5, 2026
10 checks passed
@vincentkoc vincentkoc deleted the codex/test-anthropic-cli-auth-login branch April 5, 2026 10:02
@greptile-apps

greptile-apps Bot commented Apr 5, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR hardens the host-managed Claude CLI auth path end-to-end: it scrubs inherited Claude env/config/plugin roots (ANTHROPIC_*, CLAUDE_CODE_*) from the subprocess, forces --setting-sources user to prevent repo-local .claude settings from leaking into OpenClaw-managed sessions, normalises malformed --permission-mode overrides and the legacy --dangerously-skip-permissions flag, fixes the claude-cli migration to replace (not deep-merge) the model allowlist so stale anthropic/* entries are not preserved, and switches image hydration to a content-addressed stable path for prompt-cache reuse.

All changes are intentional security hardening with one P2 note: the openclaw-cli-images/ cache now has no eviction mechanism since cleanup is a no-op.

Confidence Score: 5/5

Safe to merge — all changes are intentional security hardening with no correctness regressions identified.

No P0 or P1 findings. The single P2 note (unbounded image-cache growth) is an acknowledged design tradeoff documented with an inline comment. The env scrubbing, permission-mode normalisation, setting-sources enforcement, and migration model-allowlist replace logic are all correct. The PR's scoped serial-test evidence covers the touched path.

src/agents/cli-runner/helpers.ts (no-op cleanup); extensions/anthropic/cli-shared.ts (new normalizer logic — reviewed and correct)

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/agents/cli-runner/helpers.ts
Line: 258-259

Comment:
**No-op cleanup accumulates images indefinitely**

The content-addressed path is sound for prompt-cache stability, but `cleanup` is now a strict no-op — every unique image written to `openclaw-cli-images/` stays on disk forever with no eviction. Long-running sessions or workflows with varied images will grow this directory without bound. A background LRU sweep or max-age cull (e.g., files older than N days) would keep the cache bounded.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(agents): harden host-managed claude-..." | Re-trigger Greptile

Comment on lines +258 to 259
const cleanup = async () => {};
return { paths, cleanup };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 No-op cleanup accumulates images indefinitely

The content-addressed path is sound for prompt-cache stability, but cleanup is now a strict no-op — every unique image written to openclaw-cli-images/ stays on disk forever with no eviction. Long-running sessions or workflows with varied images will grow this directory without bound. A background LRU sweep or max-age cull (e.g., files older than N days) would keep the cache bounded.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/cli-runner/helpers.ts
Line: 258-259

Comment:
**No-op cleanup accumulates images indefinitely**

The content-addressed path is sound for prompt-cache stability, but `cleanup` is now a strict no-op — every unique image written to `openclaw-cli-images/` stays on disk forever with no eviction. Long-running sessions or workflows with varied images will grow this directory without bound. A background LRU sweep or max-age cull (e.g., files older than N days) would keep the cache bounded.

How can I resolve this? If you propose a fix, please make it concise.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7eb2e042db

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +79 to +83
// Provider auth migrations can intentionally replace the exact allowlist.
models: patchModels as NonNullable<
NonNullable<OpenClawConfig["agents"]>["defaults"]
>["models"],
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve existing model allowlist when applying auth patches

applyProviderAuthConfigPatch now replaces agents.defaults.models with the patch payload whenever that field is present, which turns partial auth patches into destructive updates. Existing OAuth auth flows commonly return only provider-local/default entries (for example via buildOauthProviderAuthResult), so running auth for one provider can silently drop previously configured model aliases/allowlist entries from other providers instead of merging them. This is a behavior regression from the prior recursive merge and can unexpectedly remove models users still rely on after login.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling commands Command implementations extensions: anthropic gateway Gateway runtime maintainer Maintainer-authored PR size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant