Add persistent browser auth to connector canvas#2364
Merged
codemillmatt merged 7 commits intoJul 20, 2026
Conversation
Replace Azure CLI-only authentication with InteractiveBrowserCredential, protected sign-in lifecycle endpoints, and subscription refresh after sign-in. Persist the Azure Identity cache securely across extension reloads and align connector restart guidance with the GitHub Copilot app. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Replaces Azure CLI authentication with persistent interactive browser authentication for the Connector Namespaces extension.
Changes:
- Adds an Azure Identity authentication broker with encrypted cache persistence.
- Adds protected sign-in endpoints and subscription refresh UI.
- Updates tests, dependencies, versions, and restart guidance.
Show a summary per file
| File | Description |
|---|---|
extensions/connector-namespaces/auth.mjs |
Implements persistent interactive authentication. |
extensions/connector-namespaces/auth.test.mjs |
Tests authentication lifecycle and persistence. |
extensions/connector-namespaces/armClient.mjs |
Uses the new token broker and refreshable subscription cache. |
extensions/connector-namespaces/server.mjs |
Adds sign-in and subscription endpoints. |
extensions/connector-namespaces/server.test.mjs |
Tests protected authentication routes and setup states. |
extensions/connector-namespaces/renderer.mjs |
Adds browser sign-in UI and app restart guidance. |
extensions/connector-namespaces/renderer.test.mjs |
Tests sign-in UI and restart messaging. |
extensions/connector-namespaces/install.reauth.test.mjs |
Replaces fake CLI authentication with broker stubbing. |
extensions/connector-namespaces/review-fixes.test.mjs |
Updates authentication implementation checks. |
extensions/connector-namespaces/test/smoke.mjs |
Adds interactive authentication to smoke testing. |
extensions/connector-namespaces/test/README.md |
Documents browser authentication for smoke tests. |
extensions/connector-namespaces/README.md |
Documents authentication persistence and usage. |
extensions/connector-namespaces/preview/README.md |
Updates restart-banner terminology. |
extensions/connector-namespaces/package.json |
Adds Azure Identity dependencies and bumps version. |
extensions/connector-namespaces/.github/plugin/plugin.json |
Bumps extension metadata version. |
.github/plugin/marketplace.json |
Publishes the updated marketplace version. |
Review details
- Files reviewed: 16/16 changed files
- Comments generated: 4
- Review effort level: Medium
Rewrite the extension documentation around the GitHub Copilot app experience, add official Connector Namespace guidance, and align marketplace metadata with the public-facing product description. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep terminal sign-in status retry-safe, preserve operational Azure Identity errors, retry transient legacy-cache cleanup, clarify secure persistence requirements, and fix the blocking spelling check. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Treat malformed authentication records as missing so browser sign-in can recover, preserve real file-read failures, and pin the Azure Identity persistence dependencies exactly. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (1)
extensions/connector-namespaces/auth.mjs:165
startSignIn()allows multiple pending browser flows even though they all write the same authentication-record file and replace the broker's singlecredential/accessToken. Reloading the canvas during sign-in (or opening it twice) can therefore authenticate two accounts concurrently; completion order can make one session reportdonewhile subscriptions come from the other account, and can leave the persisted record selecting a different account after restart. Reuse the existing pending session (or otherwise serialize interactive sign-ins) before creating another credential.
startSignIn() {
this.pruneSessions();
const sessionId = this.createSessionId();
const abortController = new AbortController();
- Files reviewed: 17/17 changed files
- Comments generated: 0 new
- Review effort level: Medium
codemillmatt
approved these changes
Jul 20, 2026
Contributor
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (1)
extensions/connector-namespaces/auth.mjs:192
- Cancellation can still persist a completed login during the post-authentication phase. After
authenticate()resolves, this code awaits record I/O and token acquisition before marking the sessiondone; a Cancel request during either await still seespending, marks the session cancelled, yet this continuation can writeazure-auth-record.json(andauthenticate()has already populated the secure cache). The UI therefore reports cancellation but the account can be restored after restart. Recheck session ownership immediately after authentication and make the commit/finalization phase non-cancellable (or otherwise prevent persistence once cancellation wins); cover cancellation whilesaveAuthRecordis blocked.
await this.saveAuthRecord(authenticationRecord);
const accessToken = await credential.getToken(this.scope, { abortSignal: abortController.signal });
- Files reviewed: 17/17 changed files
- Comments generated: 1
- Review effort level: Medium
Comment on lines
+162
to
+165
| startSignIn() { | ||
| this.pruneSessions(); | ||
| const sessionId = this.createSessionId(); | ||
| const abortController = new AbortController(); |
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.
Pull Request Checklist
npm startand verified thatREADME.mdis up to date.mainbranch for this pull request.Description
The MCP Connectors canvas previously relied exclusively on
az account get-access-token. Users without an existing Azure CLI session reached a dead-end error instead of being able to authenticate from the canvas.This update replaces that dependency with an app-native Azure authentication flow:
InteractiveBrowserCredentialfrom@azure/identitywith automatic browser launch disabled outside the explicit sign-in action.@azure/identity-cache-persistenceand restores the selected non-secret authentication record across GitHub Copilot app restarts.The existing loopback binding, capability-token protection, and
TextOnlyContent: falseMCP configuration behavior remain unchanged.Type of Contribution
Additional Notes
Validation completed:
npm run plugin:validatenpm run buildOn Linux and WSL, secure persistence requires a Secret Service-compatible keyring and
libsecret; unencrypted fallback is intentionally disabled. Access and refresh tokens remain in encrypted OS storage, while the local authentication record contains only non-secret account metadata needed to restore the selected account.By submitting this pull request, I confirm that my contribution abides by the Code of Conduct and will be licensed under the MIT License.