mirror of
https://github.com/microsoft/vscode.git
synced 2026-08-18 21:36:52 +01:00
* Share secrets between Code and Agents app via macOS Keychain Add a shared keychain service that stores secrets directly in the macOS Keychain, allowing Code and its embedded Agents app to share auth tokens without re-authentication. Architecture: - ISharedKeychainService (common interface) with ISharedKeychainMainService running in the Electron main process, exposed to renderer via IPC - SharedKeychainMainService wraps @vscode/macos-keychain native addon - NativeSecretStorageService now writes to both the shared keychain and the legacy safeStorage+SQLite pipeline (for rollback safety) - On read, shared keychain is tried first, falling back to legacy Product configuration: - darwinSharedKeychainServiceName: per-flavor service name for data isolation between Stable/Insiders/Exploration - Access group auto-detected from entitlements by the native addon Key design decisions: - Shared keychain only used when type is 'persisted' (not in-memory) - BaseSecretStorageService refactored to expose protected _doGet/_doSet/ _doDelete/_doGetKeys for use by subclasses within sequencer tasks - Native addon is an optional dependency (macOS-only) Files: - build/azure-pipelines/darwin/app-entitlements.plist (keychain-access-groups) - src/vs/platform/secrets/common/sharedKeychainService.ts (interface) - src/vs/platform/secrets/electron-main/sharedKeychainMainService.ts (impl) - src/vs/workbench/services/secrets/electron-browser/sharedKeychainService.ts (IPC proxy) - src/vs/workbench/services/secrets/electron-browser/secretStorageService.ts (wiring) Issue: #308028 * Address review feedback * Add one-time migration of legacy secrets to shared keychain On first secret operation, migrate all existing secrets from the legacy safeStorage+SQLite pipeline into the shared macOS Keychain. This ensures the Agents app can read secrets that were stored before the shared keychain was introduced. - Migration is lazy (triggered on first get/set/delete/keys) - Guarded by a 'sharedKeychain.migrationDone' storage flag - Idempotent: keychain writes are upserts, re-running is safe - Best-effort per key: individual failures don't block the rest - Skipped when type is 'in-memory' - Also: make set() in SharedKeychainMainService best-effort (log, don't throw) * update the current implementation * restrict shared keychain to CROSS_APP_SHARED_SECRET_KEYS * kick off shared keychain migration eagerly in constructor * update @vscode/macos-keychain to 0.0.1 * Use provisioning profile for keychain access groups when available During signing, check for build/darwin/distribution.provisionprofile. If present, use it as the provisioning profile and keep the keychain-access-groups entitlement in app-entitlements.plist. If not present (e.g. OSS builds), strip the keychain-access-groups section from a temp copy of the entitlements plist to avoid signing failures. The shared keychain still works via the app's default keychain without access-group isolation. * Add entitlements diagnostic dump after signing Dump the actual entitlements from the signed binary to validate whether $(TeamIdentifierPrefix) is being expanded by codesign. Hypothesis: the variable is passed literally to the entitlements plist without expansion, causing a mismatch with the provisioning profile and resulting in Killed: 9 on launch. * Exclude provisioning profile from unicode hygiene check * update package-lock.json * Adopt multiple provision profiles * fix: expand teamidentifier in the entitlement * Re-sign without provisioning profile for tests Run the entitlements step twice in CI: 1. First with provisioning profile (keychain-access-groups) for codesign/notarize 2. Then without provisioning profile for tests (in parallel with codesign) This avoids making codesign sequential with tests while still supporting the keychain-access-groups entitlement that requires a provisioning profile. - Add --skip-provisioning-profile flag to sign.ts - Add 'Set Hardened Entitlements (for tests)' pipeline step * Skip plist modifications when re-signing for tests The plutil -insert calls fail on the second sign pass because the keys already exist from the first pass. Skip plist modifications when --skip-provisioning-profile is set since they are not needed. * Move shared keychain migration from renderer to main process Replace crossAppIPC-based secret handshake with direct shared keychain writes in the main process: - MacOSCrossAppSecretSharing now reads safeStorage+SQLite and writes to shared keychain via SharedKeychainMainService (no crossAppIPC needed) - Code.app migrates on startup; Agents app spawns Code.app once if keychain is incomplete - NativeSecretStorageService no longer does migration — just reads/writes shared keychain for cross-app keys * Add isMacintosh guards before using the shared keychain service Co-authored-by: Copilot <copilot@github.com> * Remove spec * Tweak comments --------- Co-authored-by: deepak1556 <hop2deep@gmail.com> Co-authored-by: Copilot <copilot@github.com>