Skip to content

Preserve Claude secure storage config dir on restore - #9416

Closed
austinywang wants to merge 2 commits into
mainfrom
fix-claude-securestorage-config-dir-allowlist
Closed

austinywang wants to merge 2 commits into
mainfrom
fix-claude-securestorage-config-dir-allowlist

Conversation

@austinywang

@austinywang austinywang commented Aug 3, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #9412

Summary

  • Rebased on origin/main, which now contains PR Preserve CLAUDE_SECURESTORAGE_CONFIG_DIR across agent restore #9419's minimal CLAUDE_SECURESTORAGE_CONFIG_DIR allowlist change.
  • Add a regression-first test commit for Claude secure-storage restore behavior, including the non-Claude exclusion case and secret exclusion checks.
  • Centralize Claude auth-selection keys in AgentLaunchEnvironmentPolicy so app restore, CLI resume binding, and session-list startup input mark the same replayed keys in CMUX_PRESERVE_CLAUDE_AUTH_SELECTION_ENV_KEYS.
  • Add launch-capture metadata for the meaningful absent case: new Claude captures that did not have CLAUDE_SECURESTORAGE_CONFIG_DIR record CMUX_CLEAR_CLAUDE_AUTH_SELECTION_ENV_KEYS=CLAUDE_SECURESTORAGE_CONFIG_DIR, and restore/wrapper paths clear inherited ambient secure-storage only for that explicit marker.

Claude auth-selection marker decision

CLAUDE_SECURESTORAGE_CONFIG_DIR belongs in the narrower Claude auth-selection marker list because it selects which Claude credential store is read, in the same account-selecting class as CLAUDE_CONFIG_DIR.

I did not add it to the wrapper's broad stale-auth scrub list for fresh launches. Fresh cmux claude or third-party Claude launches should be allowed to inherit an intentional secure-storage selector. The wrapper now clears it only when cmux captured an explicit absence marker for a restore. Existing records without the marker cannot distinguish “absent at launch” from “dropped by the old allowlist bug,” so this PR avoids inventing that state retroactively.

Tests

  • Red test commit: edb1166406 Add Claude secure storage env regression tests
  • Green fix commit: 2725164917 Preserve Claude secure storage config dir
  • swift test --package-path Packages/macOS/CMUXAgentLaunch --filter 'AgentLaunchEnvironmentPolicyTests|AgentRestoreLaunchTests/structuredClaude'
  • swift test --package-path Packages/macOS/CMUXAgentLaunch
  • python3 tests/test_claude_wrapper_hooks.py
  • xcodebuild -project cmux.xcodeproj -scheme cmux-unit -configuration Debug -destination 'platform=macOS' -derivedDataPath /tmp/cmux-claude-securestorage test -only-testing:cmuxTests/CLINotifyProcessIntegrationRegressionTests/testClaudePromptSubmitResumeBindingPersistsSafeAuthSelectionValues -only-testing:cmuxTests/CLINotifyProcessIntegrationRegressionTests/testClaudePromptSubmitResumeBindingMarksAbsentSecureStorageConfigDirForClearing
  • git diff --check origin/main...HEAD
  • ./scripts/reload.sh --tag claude-securestorage

Tagged build: http://127.0.0.1:17320/claude-securestorage

Localization audit: no user-facing strings changed.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Claude environment restore

Layer / File(s) Summary
Environment policy updates
Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchEnvironmentPolicy.swift
The policy centralizes Claude authentication keys, allowlists CLAUDE_SECURESTORAGE_CONFIG_DIR, and removes Claude-only values for non-Claude agents.
Restore and resume integration
CLI/CMUXCLI+SessionsListForkStartupInput.swift, CLI/cmux.swift, Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentRestorePlanner.swift, Sources/RestorableAgentSession.swift
Restore and resume paths use the shared Claude authentication key collection.
Restore behavior validation
Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/*, cmuxTests/CLINotifyProcessIntegrationRegressionTests.swift
Tests verify secure-storage preservation, secret filtering, auth markers, and resume binding persistence.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: azooz2003-bit, lawrencecchen


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 warning, 2 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Cmux Swift Actor Isolation ❓ Inconclusive Need inspect Swift concurrency settings and changed declaration contexts before assessing actor isolation. Inspect package and target settings, then verify whether changed APIs are implicitly MainActor-isolated or used across actors.
Cmux User-Facing Error Privacy ❓ Inconclusive The worktree has no diff, so the production changes to assess are not yet identified. Provide the pull request diff or check out the PR commit with its parent available.
✅ Passed checks (22 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes add the required allowlist entry, preserve Claude account selection, exclude secrets, and include regression tests for issue #9412.
Out of Scope Changes check ✅ Passed The implementation, shared policy refactor, and regression tests directly support the linked issue objectives without unrelated changes.
Cmux Swift Blocking Runtime ✅ Passed The Swift diff only centralizes environment-key metadata and filtering; no blocking or timing primitives were added, and prohibited primitive counts are unchanged from the parent.
Cmux Browser Automation Off-Main ✅ Passed The full PR diff changes only agent environment and restore files; it contains no browser socket command, routing, WebKit/AppKit access, or worker-lane change.
Cmux Expensive Synchronous Load ✅ Passed The diff only centralizes environment-key sets and adds filtering; it adds no history-store, transcript, JSON, directory-scan, or synchronous loader call. The existing index loader region is unchan...
Cmux Cache Substitution Correctness ✅ Passed The diff adds a static key policy and allowlist entry; restore paths still filter the passed captured environment, with no fresh authoritative read replaced by a cache.
Cmux No Hacky Sleeps ✅ Passed The PR changes only Swift files, and the diff adds no sleep, delay, timer, polling, or wall-clock wait constructs covered by this non-Swift rule.
Cmux Algorithmic Complexity ✅ Passed The PR adds only fixed-size Set lookups and one-key exclusion; existing environment sorting/filtering remains linear and unchanged, with no nested or per-target rescan introduced.
Cmux Swift Concurrency ✅ Passed The full PR range adds no Dispatch, Combine, completion-handler, or fire-and-forget Task patterns; it only refactors environment-key filtering and adds synchronous tests.
Cmux Swift @Concurrent ✅ Passed The diff changes only environment-policy sets, filtering, and tests; it adds no async, nonisolated, @concurrent, actor-isolation, or async call-site changes.
Cmux Swift Package Boundaries ✅ Passed The diff keeps policy logic in the independently tested CMUXAgentLaunch SwiftPM target; app and CLI files only consume its public API and remove duplicated local sets.
Cmux Swiftpm Lockfiles ✅ Passed PR range changes only Swift source/tests; no Package.swift, Package.resolved, .gitignore, workflow, or Xcode project changes. CMUXAgentLaunch has no external dependencies.
Cmux Swift Logging ✅ Passed The PR diff adds no print, debugPrint, dump, NSLog, Logger, file/stdout diagnostics, or logging changes; secret names appear only in policy data and test assertions.
Cmux Full Internationalization ✅ Passed The diff changes environment-key policy and marker logic plus tests/comments; it adds no user-facing text, localization catalogs, web messages, or locale changes.
Cmux Swiftui State Layout ✅ Passed The diff changes environment-policy, CLI resume, restore-planner, and tests only; no SwiftUI views, state wrappers, GeometryReader, lazy rows, or render-time state writes were added.
Cmux Architecture Rethink ✅ Passed The diff centralizes Claude key metadata in AgentLaunchEnvironmentPolicy, preserves clear policy ownership, and adds no timing, blocking, mutable-state, observer, or UI lifecycle mechanisms.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed The diff changes environment-policy code and tests only; it adds no NSWindow, NSPanel, Window, WindowGroup, controller, shortcut, or auxiliary-window identifier code.
Cmux Source Artifacts ✅ Passed All seven changed paths are Swift source or test files; the diff adds no logs, screenshots, caches, temp folders, build output, or other source-control artifacts.
Cmux No Test Or Debug Seam In Production Source ✅ Passed Changed production Sources add environment-policy data and filtering only; no test/debug guards or seam-named members. The public key set has callers in CLI, restore, and session startup paths.
Cmux No Ambient Global State ✅ Passed The production diff adds only static let constants and instance behavior on existing constructable AgentLaunchEnvironmentPolicy; it adds no free function, mutable global, namespace type, or singleton.
Title check ✅ Passed The title clearly identifies the primary change: preserving Claude secure-storage configuration during restore.
Description check ✅ Passed The description provides a detailed summary and extensive testing evidence, although it omits several template sections and checklist confirmations.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-claude-securestorage-config-dir-allowlist

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@austinywang
austinywang force-pushed the fix-claude-securestorage-config-dir-allowlist branch from 0da30ac to 1c12b1d Compare August 3, 2026 02:10

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchEnvironmentPolicy.swift`:
- Around line 168-172: Update the environment-kind handling around the
normalizedKind cleanup so a nil kind cannot preserve Claude-only state. Require
a selected kind before replaying Claude-only environment data, or route nil
through the existing removal loop for claudeOnlyEnvironmentKeys, including
CLAUDE_SECURESTORAGE_CONFIG_DIR, while preserving the current behavior for
recognized Claude and non-Claude kinds.
- Around line 63-67: Update AgentRestorePlanner to use a shared Claude-kind
predicate based on claudeEnvironmentKinds when emitting
CMUX_PRESERVE_CLAUDE_AUTH_SELECTION_ENV in
restoredEnvironment(for:request:kind:). Ensure claudeteams and claude-teams
receive the marker whenever CLAUDE_CONFIG_DIR or CLAUDE_SECURESTORAGE_CONFIG_DIR
is selected, matching selectedRestoreEnvironment(from:kind:).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: be01fb2d-66c3-45a1-9f00-324743e7698e

📥 Commits

Reviewing files that changed from the base of the PR and between 0da30ac and 1c12b1d.

📒 Files selected for processing (7)
  • CLI/CMUXCLI+SessionsListForkStartupInput.swift
  • CLI/cmux.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchEnvironmentPolicy.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentRestorePlanner.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentLaunchEnvironmentPolicyTests.swift
  • Sources/RestorableAgentSession.swift
  • cmuxTests/CLINotifyProcessIntegrationRegressionTests.swift

@austinywang
austinywang force-pushed the fix-claude-securestorage-config-dir-allowlist branch 2 times, most recently from ea8d91a to 34666b4 Compare August 3, 2026 02:40
@austinywang
austinywang force-pushed the fix-claude-securestorage-config-dir-allowlist branch from 34666b4 to 2725164 Compare August 3, 2026 02:51
@cursor

cursor Bot commented Aug 3, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@lawrencecchen lawrencecchen added the stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening. label Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Restored Claude agents lose their account: CLAUDE_SECURESTORAGE_CONFIG_DIR is dropped by the launch-env allowlist

3 participants