microsoft / microsoft/vscode

MSAL: stale session records in SecretStorage cause Settings Sync sign-out every ~1h

Open
#332,126 3 comments 5 reactions 1 assignee Claimed by @TylerLeonhardt View on GitHub
Dominant language
TypeScript
Stars
193k
Forks
42.4k
PR merge metrics
PR metrics pending

Description

Does this issue occur when all extensions are disabled?: Yes (provider is the built-in `vscode.microsoft-authentication`)

- VS Code Version: 1.133.x and 1.134.0 (stable); `@azure/msal-node-extensions@5.3.2` per log
- OS Version: Windows 10 22H2 and Windows 11 (x64); macOS Sonoma 14.x (arm64)

Related: #242814 (same broker error code 3399614467; the `classic` workaround no longer exists), #291146, #291738 (same `tag_7cisv` on startup).

## Summary

Settings Sync with a **personal Microsoft account** signs out roughly 30–60 minutes after every login, on Windows and macOS alike, with both `microsoft-authentication.implementation: msal` and `msal-no-broker`.

Root cause, confirmed by inspecting SecretStorage and by the fix below: the extension's SecretStorage had accumulated **five session records for the same account** plus **two MSAL cache (PCA) entries in legacy and current key formats** for the same client ID. Interactive re-login adds a new session record but never removes the old ones or the legacy PCA cache. On the first silent refresh after the access token expires (~1h), `getAllSessionsForPca` ends up using a refresh token issued months earlier (2026-05-20 in my case); the server rejects it, the account is skipped, `getSessions` returns 0 sessions, and Settings Sync shows "Sign in to Sync Settings".

That stale token hit its 90-day inactivity limit on 2026-08-18, which is why the symptom appeared right after updating to 1.133 — the update itself looks coincidental. Accounts → Sign out does **not** remove the stale records. Deleting the extension's keys from `state.vscdb` does, and the account then stays signed in (verified on both OSes).

## Steps to Reproduce

1. Use a personal MS account (`user@outlook.com`) for Settings Sync for several months across VS Code updates (so legacy cache keys exist).
2. Accounts menu → Sign out → Sign in again with the same account (Windows via WAM broker, or `msal-no-broker` on either OS).
3. Wait ~1 hour (access token expiry); the next Settings Sync interval triggers a silent refresh.
4. `Microsoft Authentication` output shows `failed to acquire token silently, skipping account` → `returned 0 session(s)`; the Settings Sync badge appears.
5. Repeat 2–4: every fresh login lasts ~1 hour.

## Evidence

### SecretStorage contents before the fix (Windows, `state.vscdb`)

```
sqlite3 state.vscdb "select key from ItemTable where key like '%microsoft-authentication%' or key like '%vscode.login%';"

secret://{"extensionId":"vscode.microsoft-authentication","key":"accounts-AzureCloud"}
secret://{"extensionId":"vscode.microsoft-authentication","key":"accounts-AzureCloud-aebc6443-996d-45c2-90f0-388ff96faa56-https://login.microsoftonline.com/organizations"}
secret://{"extensionId":"vscode.microsoft-authentication","key":"f8cdef31-a31e-4b4a-93e4-5f571e91255a/1:live.com:/377a0ad8-9152-471b-9357-de0b7a147179"}
secret://{"extensionId":"vscode.microsoft-authentication","key":"f8cdef31-a31e-4b4a-93e4-5f571e91255a/1:live.com:/6747d3fa-2783-45e0-94a7-65a85ae1f799"}
secret://{"extensionId":"vscode.microsoft-authentication","key":"f8cdef31-a31e-4b4a-93e4-5f571e91255a/1:live.com:/6d52d711-ff2e-4667-90e3-3fca041c8b60"}
secret://{"extensionId":"vscode.microsoft-authentication","key":"f8cdef31-a31e-4b4a-93e4-5f571e91255a/1:live.com:/b90372be-f945-4a32-b2a3-d22868553025"}
secret://{"extensionId":"vscode.microsoft-authentication","key":"f8cdef31-a31e-4b4a-93e4-5f571e91255a/1:live.com:/ce323329-f19b-41b2-94af-402bc3f141c2"}
secret://{"extensionId":"vscode.microsoft-authentication","key":"microsoft.login.keylist"}
secret://{"extensionId":"vscode.microsoft-authentication","key":"pca:aebc6443-996d-45c2-90f0-388ff96faa56"}
secret://{"extensionId":"vscode.microsoft-authentication","key":"pca:{\"clientId\":\"aebc6443-996d-45c2-90f0-388ff96faa56\",\"authority\":\"https://login.microsoftonline.com/organizations\"}"}
secret://{"extensionId":"vscode.microsoft-authentication","key":"publicClientApplications-AzureCloud"}
secret://{"extensionId":"vscode.microsoft-authentication","key":"publicClients-AzureCloud"}
vscode.microsoft-authentication
```

Observations:
- **5 session records** for a single MSA (`1:live.com:`), one per past sign-in. None were removed by Accounts → Sign out.
- **2 PCA cache entries** for the same client ID: legacy `pca:` and current `pca:{"clientId","authority"}`. The legacy cache was never deleted after the key format changed; this is the likely home of the 2026-05-20 refresh token.
- **2 account-list keys** (`accounts-AzureCloud` vs `accounts-AzureCloud--`), same pattern.
- `microsoft.login.keylist` is a leftover from the removed `classic` implementation.

### macOS, `msal-no-broker` — stale refresh token used minutes after a fresh login

```
2026-08-22 20:52:06.147 [info] [getSessions] [email offline_access openid profile] starting
2026-08-22 20:52:06.625 [info] [getAllSessionsForPca] [email offline_access openid profile] [user@outlook.com] failed to acquire token silently, skipping account {"errorCode":"invalid_grant","errorMessage":"AADSTS700082: The refresh token has expired due to inactivity. The token was issued on 2026-05-20T09:56:03.7597431Z and was inactive for 90.00:00:00. Trace ID: 25571394-87be-457b-98fb-4077380a8c00 Correlation ID: 17025c53-72ee-416b-ab28-f1ffd53d4896 Timestamp: 2026-08-22 11:52:10Z","subError":"bad_token","correlationId":"17025c53-72ee-416b-ab28-f1ffd53d4896","name":"InteractionRequiredAuthError","timestamp":"2026-08-22 11:52:10Z","traceId":"25571394-87be-457b-98fb-4077380a8c00","claims":"","errorNo":700082}
2026-08-22 20:52:06.626 [info] [getSessions] [email offline_access openid profile] returned 0 session(s)
```

Note the token issue date (2026-05-20) versus the interactive login that happened less than an hour before this log.

### Windows, `msal` (native broker) — same account twice in WAM, then AADSTS9002313

Startup:
```
2026-08-22 18:32:50.891 [info] [aebc6443-...] Native Broker enabled: true
2026-08-22 18:32:50.915 [warning] ... @azure/msal-node-extensions@5.3.2 : Warning - [MSAL:0002] WARNING ReadAccountById:601 Account id is empty - account not found
2026-08-22 18:32:52.066 [error] ... @azure/msal-node-extensions@5.3.2 : Error - [MSAL:0002] ERROR Create:27 Created an error: tag_7cisv, StatusInternal::Unexpected, SubStatusInternal::0
```

Two `LogAccountInfoNoThrow` blocks for the **same** `home_account_id` / `preferred_username` with different realm and audience (PII redacted):

```
# record 1 — issued to the VS Code client
"aud":"aebc6443-996d-45c2-90f0-388ff96faa56","authority_type":"MSSTS","environment":"login.windows.net",
"home_account_id":".9188040d-6c67-4c5b-b112-36a304b66dad","realm":"f8cdef31-a31e-4b4a-93e4-5f571e91255a",
"iss":"https://login.microsoftonline.com/f8cdef31-a31e-4b4a-93e4-5f571e91255a/v2.0","preferred_username":"user@outlook.com",
"debug_info":"Account from: cache_token_response, ... timestamp: 2026-08-22T08:12:24.000Z","xms_idrel":"12 15"

# record 2 — OS-level MSA (Windows sign-in account), many wam_account_ids
"aud":"00000000-0000-0000-0000-0000480728C5","authority_type":"MSSTS","environment":"login.windows.net",
"home_account_id":".9188040d-6c67-4c5b-b112-36a304b66dad","realm":"9188040d-6c67-4c5b-b112-36a304b66dad",
"iss":"https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/v2.0","preferred_username":"user@outlook.com",
"debug_info":"Account from: cache_token_response, ... timestamp: 2026-08-22T08:59:02.000Z","xms_idrel":"3 2"
```

Silent acquire right after:
```
2026-08-22 18:32:52.097 [info] [getSessions] [email offline_access openid profile] starting
2026-08-22 18:32:52.100 [warning] ... WARNING TryEnqueueMsaDeviceCredentialAcquisitionAndContinue:1092 MsaDeviceOperationProvider is not available. Not attempting to register the device.
2026-08-22 18:32:52.109 [warning] ... WARNING DiscardAccessAndIdTokensIfUnusable:855 No access token found in the cache
2026-08-22 18:32:52.109 [warning] ... WARNING GetPlatformPropertiesFromStorage:2082 No account found in cache.
2026-08-22 18:32:52.646 [error] ... ERROR ErrorInternalImpl:134 Created an error: 7rhah, StatusInternal::InteractionRequired, InternalEvent::None, Error Code 3399614467, Context 'V2Error: invalid_grant AADSTS9002313: Invalid request. Request is malformed or invalid. Trace ID: 887d5357-6c2e-416f-b27a-61f905aa6000 Correlation ID: 6df74a56-d504-464c-b7e1-a125955b833f Timestamp: 2026-08-22 09:32:52Z'
2026-08-22 18:32:52.646 [info] [getAllSessionsForPca] [email offline_access openid profile] [user@outlook.com] failed to acquire token silently, skipping account {"errorCode":"interaction_required",...,"platformBrokerError":{"errorCode":"InteractionRequired","errorMessage":"V2Error: invalid_grant AADSTS9002313: ...","statusCode":3399614467,"tag":"7rhah"}}
2026-08-22 18:32:52.646 [info] [getSessions] [email offline_access openid profile] returned 0 session(s)
2026-08-22 18:32:52.646 [info] [getSessions] [499b84ac-1321-427f-aa17-267ca6975798/.default offline_access] starting
...
2026-08-22 18:32:53.107 [info] [getSessions] [499b84ac-1321-427f-aa17-267ca6975798/.default offline_access] returned 0 session(s)
```

### After the workaround (macOS, `msal-no-broker`, ~1h after login) — refresh succeeds

```
2026-08-22 22:00:53.048 [info] [getSessions] [email offline_access openid profile] starting
2026-08-22 22:00:53.390 [info] [getSessions] [email offline_access openid profile] returned 1 session(s)
2026-08-22 22:00:53.402 [info] [getSessions] [499b84ac-1321-427f-aa17-267ca6975798/.default offline_access] starting
2026-08-22 22:00:53.406 [info] [getSessions] [499b84ac-1321-427f-aa17-267ca6975798/.default offline_access] returned 1 session(s)
```

Same result on Windows after applying the same steps with `msal-no-broker`.

## Expected behavior

- Interactive sign-in should replace (or invalidate) existing cached records for the same `home_account_id`, so a fresh login never falls back to an older refresh token.
- On startup the extension should migrate or delete legacy keys (`pca:`, `accounts-AzureCloud`, `microsoft.login.keylist`) instead of leaving a second, stale cache that silent acquire can still read.
- When silent acquire fails with `bad_token` / `AADSTS700082` for one record, try the other records for the same account (or drop the dead one) instead of returning 0 sessions.
- Accounts menu → Sign out should actually purge the account's records from SecretStorage.

## Workaround (verified on both OSes)

Signing out from the Accounts menu is **not** enough. Delete the extension's SecretStorage keys manually, then sign in again (on Windows, also switch to `msal-no-broker`). Listing the keys first (as above) confirms you're affected: multiple `/1:live.com:/` session keys, or both `pca:` key formats present.

macOS — quit VS Code, then:
```sh
DB=~/Library/Application\ Support/Code/User/globalStorage/state.vscdb
cp "$DB" ~/state.vscdb.bak
sqlite3 "$DB" "select key from ItemTable where key like '%microsoft-authentication%' or key like '%vscode.login%';"
sqlite3 "$DB" "delete from ItemTable where key like '%microsoft-authentication%' or key like '%vscode.login%';"
```

Windows — quit VS Code, then (cmd):
```cmd
set DB=%APPDATA%\Code\User\globalStorage\state.vscdb
copy /y "%DB%" "%DB%.bak"
sqlite3 "%DB%" "select key from ItemTable where key like '%%microsoft-authentication%%' or key like '%%vscode.login%%';"
sqlite3 "%DB%" "delete from ItemTable where key like '%%microsoft-authentication%%' or key like '%%vscode.login%%';"
rd /s /q "%LOCALAPPDATA%\Microsoft\TokenBroker\Cache"
```
and set `"microsoft-authentication.implementation": "msal-no-broker"`.

Relaunch and sign in once. The account now survives token refresh across multiple sync intervals on both machines.

## Notes

- In 2025, `classic` worked around #242814; that option has since been removed, so affected users currently have no setting-only workaround other than moving Settings Sync to a GitHub account.
- The Windows WAM path shows an additional problem (the same MSA present twice in WAM, once as the Windows sign-in account) that `msal-no-broker` sidesteps. Happy to collect more broker-specific logs if useful.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.