feat(desktop): resolve Chromium cookie keys on Linux - #7261
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: unavailable · PR result: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
1d228da to
6a2afea
Compare
There was a problem hiding this comment.
Reviewed the new ChromiumKeys module and its call sites against the Effect service conventions. Imports, Effect.fn.Return requirement typing, and dependency acquisition (yield* FileSystem.FileSystem, ChildProcessSpawner surfaced in the requirement channel and threaded through BrowserImport's captured context) all look right. Two error-modelling issues in ChromiumKeys.ts: an underlying failure is discarded instead of being preserved as cause, and the Windows DPAPI path can turn a real failure into a silently empty key reported under a misleading reason.
Posted via Macroscope — Effect Service Conventions
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR introduces a substantial cross-platform browser credential and cookie-import capability, including native keyring access and sensitive-data handling, rather than a small isolated change. An unresolved runtime concern about the bundled helper path, plus a universal-architecture build issue and newly added static-analysis suppressions, requires human review. Not approved because:
No code changes detected at Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more. |
6a2afea to
65f945a
Compare
There was a problem hiding this comment.
One finding: a typed ChromiumKeyError is re-wrapped at a translation boundary in ChromiumKeys.ts, losing its reason and nesting the error inside itself.
Posted via Macroscope — Effect Service Conventions
65f945a to
0ad3689
Compare
0ad3689 to
032f5da
Compare
There was a problem hiding this comment.
Reviewed the new ChromiumKeys module and its call sites in ChromiumCookies/BrowserImport against the Effect service conventions. Two findings on error modelling in ChromiumKeys.ts; the layer/import/dependency-acquisition side looks fine (resolveChromiumKeys takes FileSystem/ChildProcessSpawner from the environment and scopes the child process locally).
Posted via Macroscope — Effect Service Conventions
032f5da to
cfbd7b7
Compare
cfbd7b7 to
5896abd
Compare
2eff79b to
268598a
Compare
There was a problem hiding this comment.
One finding, on the new test file's diagnostic suppression. The rest of the change — the ChromiumKeys module layout, ChromiumKeyError structure with preserved cause, ChildProcessSpawner/HostProcessEnvironment acquired from the environment, requirements surfaced through Effect.fn.Return, and the now-uniform ChromiumKeyMaterial key shape with focused mixed v10/v11 coverage — matches the conventions.
Posted via Macroscope — Effect Service Conventions
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
Bugbot Autofix is ON, but a cloud agent failed to start.
Reviewed by Cursor Bugbot for commit a771eb6. Configure here.
macOS derives the OSCrypt key from a single keychain secret. Linux is looser: a database can mix `v10` records (a hardcoded `peanuts` passphrase, used when no keyring is present) and `v11` records (a libsecret/kwallet secret), so both keys are derived up front and the record's prefix picks between them. A locked or absent keyring is not fatal — those `v11` records are skipped and the rest still import. Key acquisition moves into its own `ChromiumKeys` module; `ChromiumCookies` now decrypts each record by the scheme its prefix names and skips any it holds no key for, so a partial result is reported honestly rather than failing the whole import. Windows is deliberately left out: since Chrome 127 its cookies are encrypted to the browser's own identity (App-Bound Encryption) and cannot be read by another process, so those forks are not offered there at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… key Some Linux clients encrypted OSCrypt data with a key derived from an empty passphrase (crbug.com/1195256). Chromium retries every failed v10/v11 record with that key, so records it can still read were being skipped here. The key material now carries the empty-passphrase key on Linux and the decryptor retries with it when a record's own key fails — and only then, matching Chromium: a record whose own key is missing entirely stays skipped. Also drops an unexplained diagnostics suppression from ChromiumKeys.test.ts that had nothing to suppress. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
An unprefixed cookie blob is legacy data stored in the clear, and Chromium's OSCrypt returns it as-is on both macOS and Linux (os_crypt_mac.mm and os_crypt_linux.cc alike: "old data saved as clear text"). The reader only honoured that on macOS, so a Linux import counted those rows as undecryptable and dropped otherwise readable cookies. The fallback now applies on Linux as well; Windows stays excluded, since its app-bound blobs also lack the prefix. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…x key secret-tool matched on the application attribute alone, so any other Secret Service item carrying application=chrome would supply the wrong passphrase and every v11 cookie would be skipped as undecryptable.

Stacked on #7260 (
browser-import-more-sources). Despite the retained branch name, this PR adds Linux support only; Windows Chromium is intentionally unsupported.Chromium cookie key handling moves into a platform-specific module:
peanutspassphrasesecret-tool, using the browser’sapplicationattributeLinux requires
secret-tooland a compatible Secret Service backend to import v11 records. Missing keys/tools/backend can yield a partial v10 import; skipped records are reported. Explicit permission denial or cancellation stops the import. Secret bytes are preserved apart from the tool’s output line ending.There is no DPAPI, PowerShell, App-Bound Encryption bypass, or direct KWallet implementation. macOS keeps the existing in-process consent path.
Validation: synthetic v10/v11 decryption fixtures, mocked Secret Service subprocess results, denied/missing backend behavior, and trailing-whitespace preservation. No live Linux keyring lookup was performed during this audit.
Original implementation: Claude Code. Review fixes: GPT-5.6 Sol agents, coordinated through Codex.
Note
Add Chromium cookie key resolution for Linux and Windows imports
ChromiumKeysmodule to resolve macOS, Linux, and Windows encryption keys, replacing hardcoded macOS-only keychain logic.ChromiumCookiesvalue decoder to handle v10/v11 CBC, Windows v10 GCM, and legacy cleartext, preserving partial imports when some keys are missing.ChromiumCookieReadReasonschema in ChromiumCookies.ts replaces macOS-specific failure literals with sharedChromiumKeyFailurereasons and removesunsupportedPlatform.Macroscope summarized 0da299e.
Note
High Risk
Changes how cookie encryption keys are obtained (keychain, libsecret subprocess, DPAPI) and ships a native helper that reads browser secrets—security- and privacy-sensitive paths with partial-import edge cases.
Overview
Enables Chromium-family browser cookie import on Linux by resolving encryption keys per platform instead of treating non-macOS Chromium as unsupported.
Key handling moves into
ChromiumKeys: macOS still uses the login keychain; Linux derivesv10keys from Chromium’s keyring-free passphrase,v11from Secret Service via a bundledt3-browser-secrethelper (nativelibsecret, exit codes for missing/denied/unavailable), plus an empty-passphrase retry for mis-encrypted records.ChromiumCookiesdecrypts mixedv10/v11CBC schemes, allows partial imports when only some keys exist, and aligns legacy unprefixed values with Chromium on Linux.The helper is compiled at dev/build (
build-browser-secret.mjs), wired throughLinuxBrowserSecret, shipped underresources/browser-secreton Linux artifacts, and CI/release installlibsecret-1-dev/pkg-config. Browser source definitions gainlinuxSecretApplication; Helium is listed on Linux (and Windows profile paths / running detection via held cookie DBs). Contracts and the import wizard addkeychainUnavailableas a retryable failure.The diff also includes Windows DPAPI key reading and Helium-on-Windows plumbing in the same modules; other Chromium forks on Windows remain excluded in source metadata.
Reviewed by Cursor Bugbot for commit 0da299e. Bugbot is set up for automated code reviews on this repo. Configure here.