Fix secret storage persistence in VS Code Server web#317333
Open
mutl3y wants to merge 1 commit into
Open
Conversation
Contributor
📬 CODENOTIFYThe following users are being notified based on files changed in this PR: @deepak1556Matched files:
|
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes loss of GitHub/Copilot authentication state in VS Code Server web by ensuring the web workbench always provides a persisted secretStorageProvider (backed by browser localStorage) instead of falling back to the in-memory secret storage implementation when remoteAuthority is set and the vscode-secret-key-path cookie is missing.
Changes:
- Always instantiate
LocalStorageSecretStorageProviderfor secret storage in the web workbench (removes the remote+no-cookie special case). - As a result, secrets persist across page refreshes and workspace/folder switches in server-web scenarios.
Comment on lines
616
to
620
| settingsSyncOptions: config.settingsSyncOptions ? { enabled: config.settingsSyncOptions.enabled, } : undefined, | ||
| workspaceProvider: WorkspaceProvider.create(config), | ||
| urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute), | ||
| secretStorageProvider: config.remoteAuthority && !secretStorageKeyPath | ||
| ? undefined /* with a remote without embedder-preferred storage, store on the remote */ | ||
| : new LocalStorageSecretStorageProvider(secretStorageCrypto), | ||
| secretStorageProvider: new LocalStorageSecretStorageProvider(secretStorageCrypto), | ||
| }); |
mutl3y
pushed a commit
to mutl3y/vs-code_sandbox
that referenced
this pull request
May 19, 2026
…patched in dockerfile but PR: microsoft/vscode#317333 has been raised separately
The web server never set the 'vscode-secret-key-path' or 'vscode-cli-secret-half'
cookies that workbench.ts requires to use ServerKeyedAESCrypto. Without them the
browser fell back to TransparentCrypto (no encryption) and in-memory storage,
so GitHub auth tokens and all other secrets were lost on every page refresh.
This mirrors the protocol already implemented in the CLI (cli/src/commands/serve_web.rs):
* A random 32-byte server-secret key is generated on first start and persisted
to ${userDataPath}/serve-web-key-half (mode 0600), so the key survives server
restarts and VS Code updates.
* A per-client 32-byte key half is carried in an HttpOnly cookie
'vscode-cli-secret-half' (Max-Age 30 days).
* POST /_vscode-server/mint-key returns SHA-256(serverKey || clientKeyHalf)[0:32]
as application/octet-stream. The browser XORs this with its local half to
produce the AES-256 key used by ServerKeyedAESCrypto.
* Both cookies are set on every root-page response (302 redirect and 200).
workbench.ts already contains the correct conditional to use ServerKeyedAESCrypto
when 'vscode-secret-key-path' is present, so no browser-side changes are needed.
Revert the earlier unconditional LocalStorageSecretStorageProvider override to
restore the original upstream logic.
Fixes: microsoft#317329
04fe551 to
1779f51
Compare
Author
|
@microsoft-github-policy-service agree |
Contributor
|
@connor4312 Maybe you are more familiar with this... |
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.
Fixes #317329
Problem
When using VS Code Server (
server-linux-x64-web) accessed via a browser, thesecretStorageProvideris set toundefinedwhenremoteAuthorityis set and thevscode-secret-key-pathcookie is absent. This causes all secrets (GitHub auth tokens, Copilot credentials, etc.) to be stored in-memory only — lost on every page refresh or folder switch.The CLI (
code serve-web) already implements the full mint-key protocol incli/src/commands/serve_web.rs. The Node.js server binary never did.Root cause
workbench.ts(lines 609-621) already has the correct logic:It uses
ServerKeyedAESCrypto(AES-256, keys survive page reload) whenvscode-secret-key-pathis set, falling back toTransparentCryptootherwise. But the server never set that cookie, so the browser always fell back to in-memory storage.Fix
Implement the same mint-key protocol in
webClientServer.tsthat the CLI already implements in Rust:Persistent server key — on first start, a random 32-byte server secret is generated and written to
${userDataPath}/serve-web-key-half(mode 0600). It is reloaded on every subsequent start so server restarts / VS Code updates do not invalidate stored secrets.Client key cookie — every root-page response sets
vscode-cli-secret-half(HttpOnly, SameSite=Strict, Max-Age=30 days) carrying the client's 32-byte key half.Path cookie — every root-page response also sets
vscode-secret-key-pathpointing to/_vscode-server/mint-key, telling the workbench where to fetch the server's contribution.Mint endpoint —
POST /_vscode-server/mint-keyreturnsSHA-256(serverKey || clientKeyHalf)[0:32]asapplication/octet-stream. The browser XORs this with its local half to produce the AES-256 key forServerKeyedAESCrypto.This is a direct port of
get_server_key_half,get_client_key_half,handle_secret_mint, andappend_secret_headersfromcli/src/commands/serve_web.rs. The derivation, cookie names, and file name (serve-web-key-half) are identical.Note: The mint path is
/_vscode-server/mint-key(vs the CLI's_vscode-cli/mint-key) to avoid collision if both servers ever run on the same origin.workbench.tsreads the path from the cookie so this is transparent to the browser.Changes
src/vs/server/node/webClientServer.ts— implement mint protocol (the only file changed)src/vs/code/browser/workbench/workbench.ts— reverted to upstream; no changes neededTesting
Verified with a Playwright end-to-end test against a running
server-linux-x64-webinstance (via an external mint-proxy that implements the same protocol):POST /_vscode-server/mint-keyreturns 32 bytes