feat(backend): add Linux secret-service support for OAuth token storage (ACS-293)#4
Closed
StillKnotKnown wants to merge 1 commit intodevelopfrom
Conversation
…ge (ACS-293) This commit implements Linux keychain support using the secretstorage library, bringing Linux to parity with macOS (Keychain) and Windows (Credential Files). Changes: - Add _get_token_from_linux_secret_service() function in auth.py - Uses secretstorage library for DBus communication - Searches for Claude Code credentials by application attribute - Validates token format (sk-ant-oat01- prefix) - Graceful fallback to .env when secret-service unavailable - Update get_token_from_keychain() to call Linux implementation - Update get_auth_token_source() to return "Linux Secret Service" - Update require_auth_token() error message with Linux instructions - Add secretstorage>=3.3.3 to requirements.txt (Linux-only) Testing: - Add comprehensive test suite in tests/test_auth.py (38 tests) - Environment variable token resolution - macOS keychain token retrieval - Windows credential file token retrieval - Linux secret-service token retrieval (new) - Token source detection - Error handling and edge cases Fixes ACS-293
Owner
Author
|
Recreating on upstream repository |
StillKnotKnown
pushed a commit
that referenced
this pull request
Jan 18, 2026
…ik90#1259) * fix(windows): prevent zombie process accumulation on app close - Use taskkill /f /t on Windows to properly kill process trees (SIGTERM/SIGKILL are ignored on Windows) - Make killAllProcesses() wait for process exit events with timeout - Kill PTY daemon process on shutdown - Clear periodic update check interval on app quit Fixes process accumulation in Task Manager after closing Auto-Claude. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(windows): extract killProcessGracefully utility with timer cleanup - Extract shared killProcessGracefully() to platform module - Fix Issue #1: Move taskkill outside try-catch scope - Fix Issue #2: Track exit state to skip unnecessary taskkill - Fix Issue #3: Add GRACEFUL_KILL_TIMEOUT_MS constant - Fix Issue #4: Use consistent 5000ms timeout everywhere - Fix Issue #5: Add debug logging for catch blocks - Fix Issue AndyMik90#6: Log warning when process.once unavailable - Fix Issue AndyMik90#7: Eliminate code duplication across 3 files - Fix timer leak: Clear timeout on process exit/error, unref timer Add comprehensive tests (19 test cases) covering: - Windows taskkill fallback behavior - Unix SIGTERM/SIGKILL sequence - Timer cleanup and memory leak prevention - Edge cases and error handling Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: Andy <119136210+AndyMik90@users.noreply.github.com>
StillKnotKnown
pushed a commit
that referenced
this pull request
Jan 26, 2026
…ndyMik90#1456) * auto-claude: subtask-1-1 - Add GITHUB_AUTH_CHANGED IPC channel constant * auto-claude: subtask-1-2 - Add async getGitHubTokenForSubprocess() helper to utils.ts Add a new exported async function getGitHubTokenForSubprocess() that calls getTokenFromGhCli() to retrieve fresh GitHub tokens for subprocess use. This provides a clean interface for runner-env.ts to get tokens without caching, ensuring account changes are reflected immediately. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: subtask-1-3 - Update getRunnerEnv() to include GITHUB_TOKEN * auto-claude: subtask-2-1 - Add auth change detection and event emission to oauth-handlers.ts - Add GitHubAuthChangedPayload interface for auth change events - Add sendAuthChangedToRenderer() to broadcast auth changes to all windows - Add getCurrentGitHubUsername() helper to get current GitHub user - Modify registerStartGhAuth() to: - Capture username before auth starts - Get username after successful auth - Emit GITHUB_AUTH_CHANGED event if account changed Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: subtask-3-1 - Add onGitHubAuthChanged listener to GitHubAPI interface - Add onGitHubAuthChanged to GitHubAPI interface in github-api.ts - Add implementation using createIpcListener with IPC_CHANNELS.GITHUB_AUTH_CHANGED - Add mock implementation in browser-mock.ts for testing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: subtask-4-1 - Add GitHub auth change listener to pr-review-store * fix: Address PR review findings for GitHub auth handlers - Convert getCurrentGitHubUsername() to async using promisified execFile to avoid blocking Electron main thread during auth flow (finding #1) - Make getGitHubTokenForSubprocess() truly async by introducing async getTokenFromGhCliAsync() - the sync version is preserved for getGitHubConfig (finding #2) - Add warning log when username fetch fails after successful auth, handling the edge case where auth succeeds but account change detection fails (finding #3) - Remove unused timestamp field from GitHubAuthChangedPayload interface since the renderer callback only uses oldUsername/newUsername (finding #4) - Document the intentional extraEnv override behavior in getRunnerEnv() JSDoc comment (finding #5) All 5 findings from PR review were real issues. These fixes improve code quality by avoiding main thread blocking and clarifying edge cases. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * test: Fix oauth-handlers tests for async getCurrentGitHubUsername Update test mocks and add waitForAsyncSetup helper to handle the async changes in getCurrentGitHubUsername(). The function now uses promisified execFile instead of execFileSync to avoid blocking the main thread. Key changes: - Add mockExecFile mock for the promisified execFile function - Add waitForAsyncSetup helper to wait for async setup before emitting process events - Update all affected tests to use waitForAsyncSetup before emitting mock process events Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
StillKnotKnown
pushed a commit
that referenced
this pull request
Feb 6, 2026
…ndyMik90#1747) * auto-claude: subtask-1-1 - Add errorCode propagation in reactiveTokenRefresh() * auto-claude: subtask-1-2 - Return null instead of revoked token for permanent errors in ensureValidToken() * auto-claude: subtask-1-3 - Clear credential cache on invalid_grant error in refreshOAuthToken() * auto-claude: subtask-1-4 - Clear revoked credentials on persistence failure (Bug #5) When token refresh succeeds but persistence to keychain fails, the old credentials in the keychain are now revoked server-side. This commit adds defensive cache clearing in both ensureValidToken() and reactiveTokenRefresh() to prevent serving revoked tokens from cache. On app restart, Bugs #3 and #4 fixes will handle the revoked credentials properly by returning null and clearing the cache, forcing re-authentication. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * auto-claude: subtask-2-1 - Move authFailedProfiles marking before early return --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
StillKnotKnown
pushed a commit
that referenced
this pull request
Feb 9, 2026
…ndyMik90#1456) * auto-claude: subtask-1-1 - Add GITHUB_AUTH_CHANGED IPC channel constant * auto-claude: subtask-1-2 - Add async getGitHubTokenForSubprocess() helper to utils.ts Add a new exported async function getGitHubTokenForSubprocess() that calls getTokenFromGhCli() to retrieve fresh GitHub tokens for subprocess use. This provides a clean interface for runner-env.ts to get tokens without caching, ensuring account changes are reflected immediately. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: subtask-1-3 - Update getRunnerEnv() to include GITHUB_TOKEN * auto-claude: subtask-2-1 - Add auth change detection and event emission to oauth-handlers.ts - Add GitHubAuthChangedPayload interface for auth change events - Add sendAuthChangedToRenderer() to broadcast auth changes to all windows - Add getCurrentGitHubUsername() helper to get current GitHub user - Modify registerStartGhAuth() to: - Capture username before auth starts - Get username after successful auth - Emit GITHUB_AUTH_CHANGED event if account changed Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: subtask-3-1 - Add onGitHubAuthChanged listener to GitHubAPI interface - Add onGitHubAuthChanged to GitHubAPI interface in github-api.ts - Add implementation using createIpcListener with IPC_CHANNELS.GITHUB_AUTH_CHANGED - Add mock implementation in browser-mock.ts for testing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: subtask-4-1 - Add GitHub auth change listener to pr-review-store * fix: Address PR review findings for GitHub auth handlers - Convert getCurrentGitHubUsername() to async using promisified execFile to avoid blocking Electron main thread during auth flow (finding #1) - Make getGitHubTokenForSubprocess() truly async by introducing async getTokenFromGhCliAsync() - the sync version is preserved for getGitHubConfig (finding #2) - Add warning log when username fetch fails after successful auth, handling the edge case where auth succeeds but account change detection fails (finding #3) - Remove unused timestamp field from GitHubAuthChangedPayload interface since the renderer callback only uses oldUsername/newUsername (finding #4) - Document the intentional extraEnv override behavior in getRunnerEnv() JSDoc comment (finding #5) All 5 findings from PR review were real issues. These fixes improve code quality by avoiding main thread blocking and clarifying edge cases. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * test: Fix oauth-handlers tests for async getCurrentGitHubUsername Update test mocks and add waitForAsyncSetup helper to handle the async changes in getCurrentGitHubUsername(). The function now uses promisified execFile instead of execFileSync to avoid blocking the main thread. Key changes: - Add mockExecFile mock for the promisified execFile function - Add waitForAsyncSetup helper to wait for async setup before emitting process events - Update all affected tests to use waitForAsyncSetup before emitting mock process events Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
StillKnotKnown
pushed a commit
that referenced
this pull request
Feb 9, 2026
…ndyMik90#1747) * auto-claude: subtask-1-1 - Add errorCode propagation in reactiveTokenRefresh() * auto-claude: subtask-1-2 - Return null instead of revoked token for permanent errors in ensureValidToken() * auto-claude: subtask-1-3 - Clear credential cache on invalid_grant error in refreshOAuthToken() * auto-claude: subtask-1-4 - Clear revoked credentials on persistence failure (Bug #5) When token refresh succeeds but persistence to keychain fails, the old credentials in the keychain are now revoked server-side. This commit adds defensive cache clearing in both ensureValidToken() and reactiveTokenRefresh() to prevent serving revoked tokens from cache. On app restart, Bugs #3 and #4 fixes will handle the revoked credentials properly by returning null and clearing the cache, forcing re-authentication. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * auto-claude: subtask-2-1 - Move authFailedProfiles marking before early return --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
StillKnotKnown
pushed a commit
that referenced
this pull request
Feb 9, 2026
…ndyMik90#1456) * auto-claude: subtask-1-1 - Add GITHUB_AUTH_CHANGED IPC channel constant * auto-claude: subtask-1-2 - Add async getGitHubTokenForSubprocess() helper to utils.ts Add a new exported async function getGitHubTokenForSubprocess() that calls getTokenFromGhCli() to retrieve fresh GitHub tokens for subprocess use. This provides a clean interface for runner-env.ts to get tokens without caching, ensuring account changes are reflected immediately. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: subtask-1-3 - Update getRunnerEnv() to include GITHUB_TOKEN * auto-claude: subtask-2-1 - Add auth change detection and event emission to oauth-handlers.ts - Add GitHubAuthChangedPayload interface for auth change events - Add sendAuthChangedToRenderer() to broadcast auth changes to all windows - Add getCurrentGitHubUsername() helper to get current GitHub user - Modify registerStartGhAuth() to: - Capture username before auth starts - Get username after successful auth - Emit GITHUB_AUTH_CHANGED event if account changed Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: subtask-3-1 - Add onGitHubAuthChanged listener to GitHubAPI interface - Add onGitHubAuthChanged to GitHubAPI interface in github-api.ts - Add implementation using createIpcListener with IPC_CHANNELS.GITHUB_AUTH_CHANGED - Add mock implementation in browser-mock.ts for testing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: subtask-4-1 - Add GitHub auth change listener to pr-review-store * fix: Address PR review findings for GitHub auth handlers - Convert getCurrentGitHubUsername() to async using promisified execFile to avoid blocking Electron main thread during auth flow (finding #1) - Make getGitHubTokenForSubprocess() truly async by introducing async getTokenFromGhCliAsync() - the sync version is preserved for getGitHubConfig (finding #2) - Add warning log when username fetch fails after successful auth, handling the edge case where auth succeeds but account change detection fails (finding #3) - Remove unused timestamp field from GitHubAuthChangedPayload interface since the renderer callback only uses oldUsername/newUsername (finding #4) - Document the intentional extraEnv override behavior in getRunnerEnv() JSDoc comment (finding #5) All 5 findings from PR review were real issues. These fixes improve code quality by avoiding main thread blocking and clarifying edge cases. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * test: Fix oauth-handlers tests for async getCurrentGitHubUsername Update test mocks and add waitForAsyncSetup helper to handle the async changes in getCurrentGitHubUsername(). The function now uses promisified execFile instead of execFileSync to avoid blocking the main thread. Key changes: - Add mockExecFile mock for the promisified execFile function - Add waitForAsyncSetup helper to wait for async setup before emitting process events - Update all affected tests to use waitForAsyncSetup before emitting mock process events Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
StillKnotKnown
pushed a commit
that referenced
this pull request
Feb 9, 2026
…ndyMik90#1747) * auto-claude: subtask-1-1 - Add errorCode propagation in reactiveTokenRefresh() * auto-claude: subtask-1-2 - Return null instead of revoked token for permanent errors in ensureValidToken() * auto-claude: subtask-1-3 - Clear credential cache on invalid_grant error in refreshOAuthToken() * auto-claude: subtask-1-4 - Clear revoked credentials on persistence failure (Bug #5) When token refresh succeeds but persistence to keychain fails, the old credentials in the keychain are now revoked server-side. This commit adds defensive cache clearing in both ensureValidToken() and reactiveTokenRefresh() to prevent serving revoked tokens from cache. On app restart, Bugs #3 and #4 fixes will handle the revoked credentials properly by returning null and clearing the cache, forcing re-authentication. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * auto-claude: subtask-2-1 - Move authFailedProfiles marking before early return --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
StillKnotKnown
pushed a commit
that referenced
this pull request
Feb 9, 2026
…ndyMik90#1456) * auto-claude: subtask-1-1 - Add GITHUB_AUTH_CHANGED IPC channel constant * auto-claude: subtask-1-2 - Add async getGitHubTokenForSubprocess() helper to utils.ts Add a new exported async function getGitHubTokenForSubprocess() that calls getTokenFromGhCli() to retrieve fresh GitHub tokens for subprocess use. This provides a clean interface for runner-env.ts to get tokens without caching, ensuring account changes are reflected immediately. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: subtask-1-3 - Update getRunnerEnv() to include GITHUB_TOKEN * auto-claude: subtask-2-1 - Add auth change detection and event emission to oauth-handlers.ts - Add GitHubAuthChangedPayload interface for auth change events - Add sendAuthChangedToRenderer() to broadcast auth changes to all windows - Add getCurrentGitHubUsername() helper to get current GitHub user - Modify registerStartGhAuth() to: - Capture username before auth starts - Get username after successful auth - Emit GITHUB_AUTH_CHANGED event if account changed Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: subtask-3-1 - Add onGitHubAuthChanged listener to GitHubAPI interface - Add onGitHubAuthChanged to GitHubAPI interface in github-api.ts - Add implementation using createIpcListener with IPC_CHANNELS.GITHUB_AUTH_CHANGED - Add mock implementation in browser-mock.ts for testing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: subtask-4-1 - Add GitHub auth change listener to pr-review-store * fix: Address PR review findings for GitHub auth handlers - Convert getCurrentGitHubUsername() to async using promisified execFile to avoid blocking Electron main thread during auth flow (finding #1) - Make getGitHubTokenForSubprocess() truly async by introducing async getTokenFromGhCliAsync() - the sync version is preserved for getGitHubConfig (finding #2) - Add warning log when username fetch fails after successful auth, handling the edge case where auth succeeds but account change detection fails (finding #3) - Remove unused timestamp field from GitHubAuthChangedPayload interface since the renderer callback only uses oldUsername/newUsername (finding #4) - Document the intentional extraEnv override behavior in getRunnerEnv() JSDoc comment (finding #5) All 5 findings from PR review were real issues. These fixes improve code quality by avoiding main thread blocking and clarifying edge cases. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * test: Fix oauth-handlers tests for async getCurrentGitHubUsername Update test mocks and add waitForAsyncSetup helper to handle the async changes in getCurrentGitHubUsername(). The function now uses promisified execFile instead of execFileSync to avoid blocking the main thread. Key changes: - Add mockExecFile mock for the promisified execFile function - Add waitForAsyncSetup helper to wait for async setup before emitting process events - Update all affected tests to use waitForAsyncSetup before emitting mock process events Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
StillKnotKnown
pushed a commit
that referenced
this pull request
Feb 9, 2026
…ndyMik90#1747) * auto-claude: subtask-1-1 - Add errorCode propagation in reactiveTokenRefresh() * auto-claude: subtask-1-2 - Return null instead of revoked token for permanent errors in ensureValidToken() * auto-claude: subtask-1-3 - Clear credential cache on invalid_grant error in refreshOAuthToken() * auto-claude: subtask-1-4 - Clear revoked credentials on persistence failure (Bug #5) When token refresh succeeds but persistence to keychain fails, the old credentials in the keychain are now revoked server-side. This commit adds defensive cache clearing in both ensureValidToken() and reactiveTokenRefresh() to prevent serving revoked tokens from cache. On app restart, Bugs #3 and #4 fixes will handle the revoked credentials properly by returning null and clearing the cache, forcing re-authentication. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * auto-claude: subtask-2-1 - Move authFailedProfiles marking before early return --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
StillKnotKnown
pushed a commit
that referenced
this pull request
Feb 10, 2026
…ndyMik90#1456) * auto-claude: subtask-1-1 - Add GITHUB_AUTH_CHANGED IPC channel constant * auto-claude: subtask-1-2 - Add async getGitHubTokenForSubprocess() helper to utils.ts Add a new exported async function getGitHubTokenForSubprocess() that calls getTokenFromGhCli() to retrieve fresh GitHub tokens for subprocess use. This provides a clean interface for runner-env.ts to get tokens without caching, ensuring account changes are reflected immediately. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: subtask-1-3 - Update getRunnerEnv() to include GITHUB_TOKEN * auto-claude: subtask-2-1 - Add auth change detection and event emission to oauth-handlers.ts - Add GitHubAuthChangedPayload interface for auth change events - Add sendAuthChangedToRenderer() to broadcast auth changes to all windows - Add getCurrentGitHubUsername() helper to get current GitHub user - Modify registerStartGhAuth() to: - Capture username before auth starts - Get username after successful auth - Emit GITHUB_AUTH_CHANGED event if account changed Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: subtask-3-1 - Add onGitHubAuthChanged listener to GitHubAPI interface - Add onGitHubAuthChanged to GitHubAPI interface in github-api.ts - Add implementation using createIpcListener with IPC_CHANNELS.GITHUB_AUTH_CHANGED - Add mock implementation in browser-mock.ts for testing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * auto-claude: subtask-4-1 - Add GitHub auth change listener to pr-review-store * fix: Address PR review findings for GitHub auth handlers - Convert getCurrentGitHubUsername() to async using promisified execFile to avoid blocking Electron main thread during auth flow (finding #1) - Make getGitHubTokenForSubprocess() truly async by introducing async getTokenFromGhCliAsync() - the sync version is preserved for getGitHubConfig (finding #2) - Add warning log when username fetch fails after successful auth, handling the edge case where auth succeeds but account change detection fails (finding #3) - Remove unused timestamp field from GitHubAuthChangedPayload interface since the renderer callback only uses oldUsername/newUsername (finding #4) - Document the intentional extraEnv override behavior in getRunnerEnv() JSDoc comment (finding #5) All 5 findings from PR review were real issues. These fixes improve code quality by avoiding main thread blocking and clarifying edge cases. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * test: Fix oauth-handlers tests for async getCurrentGitHubUsername Update test mocks and add waitForAsyncSetup helper to handle the async changes in getCurrentGitHubUsername(). The function now uses promisified execFile instead of execFileSync to avoid blocking the main thread. Key changes: - Add mockExecFile mock for the promisified execFile function - Add waitForAsyncSetup helper to wait for async setup before emitting process events - Update all affected tests to use waitForAsyncSetup before emitting mock process events Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
StillKnotKnown
pushed a commit
that referenced
this pull request
Feb 10, 2026
…ndyMik90#1747) * auto-claude: subtask-1-1 - Add errorCode propagation in reactiveTokenRefresh() * auto-claude: subtask-1-2 - Return null instead of revoked token for permanent errors in ensureValidToken() * auto-claude: subtask-1-3 - Clear credential cache on invalid_grant error in refreshOAuthToken() * auto-claude: subtask-1-4 - Clear revoked credentials on persistence failure (Bug #5) When token refresh succeeds but persistence to keychain fails, the old credentials in the keychain are now revoked server-side. This commit adds defensive cache clearing in both ensureValidToken() and reactiveTokenRefresh() to prevent serving revoked tokens from cache. On app restart, Bugs #3 and #4 fixes will handle the revoked credentials properly by returning null and clearing the cache, forcing re-authentication. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * auto-claude: subtask-2-1 - Move authFailedProfiles marking before early return --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Base Branch
developbranch (required for all feature/fix PRs)main(hotfix only - maintainers)Description
This PR implements Linux Secret Service API support for OAuth token storage, bringing Linux to feature parity with macOS (Keychain) and Windows (Credential Files).
The Problem (ACS-293): On Linux, the Electron app's profile system stores encrypted OAuth tokens that override the
.envfile'sCLAUDE_CODE_OAUTH_TOKEN, causing authentication failures. Since the Python backend had no Linux keychain support (returnedNone), users had to manually remove tokens from profile JSON files.The Fix: Added
_get_token_from_linux_secret_service()function that:secretstoragelibrary to communicate with the Freedesktop.org Secret Service API via DBusclaude setup-tokenCLI.envwhen secret-service is unavailableImpact: Linux users can now use
claude setup-tokento store OAuth tokens securely in their system keychain, just like macOS and Windows users. The profile token override issue is resolved because the backend can now retrieve valid tokens from the keychain.Related Issue
Closes #ACS-293
Type of Change
Area
Commit Message Format
Follow conventional commits:
<type>: <subject>Types: feat, fix, docs, style, refactor, test, chore
Example:
feat: add user authentication systemChecklist
developbranchCI/Testing Requirements
Test Coverage: Added comprehensive test suite in
tests/test_auth.pywith 38 tests covering:All tests passing (38/38).
Screenshots
Feature Toggle
use_feature_nameBreaking Changes
Breaking: No
Details:
secretstorageis not installed or DBus is unavailable, the code gracefully falls back to requiring.envfile tokensys_platform == "linux") so it only affects Linux users