Conversation
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
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)
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.
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.
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
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.
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
Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
…312472) * Add 'last two messages' cache breakpoint strategy for Messages API Adds an experiment-gated alternative to the heuristic-based cache breakpoint placement. Places cache_control on the last two merged Anthropic messages instead of using prompt-tsx markers and addCacheBreakpoints. Gated behind AnthropicCacheBreakpointsLastTwoMessages (default false, onExp). * Address PR review: handle pre-marked tail messages in addLastTwoMessagesCacheControl * Remove 'advanced' tag from cacheBreakpoints.lastTwoMessages setting
* 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>
Co-authored-by: Copilot <copilot@github.com>
* round trip permission levels to extension * address some comments
* chat: register in-place action for programmatic chat session contributions The autorun that registers `openNewChatSessionInPlace.<type>` actions filters `_contributions` by `_contributionDisposables.has(...)`. Only extension-contributed providers were getting added to that map (via `_evaluateAvailability`), so programmatically-registered contributions (local + remote agent hosts) had no in-place action and the session-type picker in VS Code threw "command not found" when switching to the local Copilot CLI agent host. Mark programmatic registrations as active in `registerChatSessionContribution` so they participate in the autorun. Also disambiguate the agent-host displayName in VS Code by suffixing "- Agent Host", since the extension-host Copilot CLI harness uses the same "Copilot CLI" label. The Agents window keeps the original displayName. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chat: refresh hasCanDelegateProviders context key on programmatic register/unregister Programmatic chat session contributions bypass _evaluateAvailability, which was the only path that called _updateHasCanDelegateProvidersContextKey. Update the context key directly in registerChatSessionContribution and its dispose so UI gated on ChatContextKeys.hasCanDelegateProviders stays in sync. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )