Skip to content

Add persistent browser auth to connector canvas#2364

Merged
codemillmatt merged 7 commits into
github:mainfrom
alexyaang:alexyaang-interactive-connector-sign-in
Jul 20, 2026
Merged

Add persistent browser auth to connector canvas#2364
codemillmatt merged 7 commits into
github:mainfrom
alexyaang:alexyaang-interactive-connector-sign-in

Conversation

@alexyaang

@alexyaang alexyaang commented Jul 20, 2026

Copy link
Copy Markdown
Member

Pull Request Checklist

  • I have read and followed the CONTRIBUTING.md guidelines.
  • I have read and followed the Guidance for submissions involving paid services.
  • My contribution adds a new instruction, prompt, agent, skill, workflow, or canvas extension file in the correct directory.
  • The file follows the required naming convention.
  • The content is clearly structured and follows the example format.
  • I have tested my instructions, prompt, agent, skill, workflow, or canvas extension with GitHub Copilot.
  • I have run npm start and verified that README.md is up to date.
  • I am targeting the main branch 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:

  • Uses InteractiveBrowserCredential from @azure/identity with automatic browser launch disabled outside the explicit sign-in action.
  • Exposes protected loopback endpoints to start, poll, and cancel sign-in.
  • Polls sign-in status from the canvas, reloads subscriptions after success, and keeps terminal results stable for repeated polling.
  • Persists tokens in the operating system's encrypted credential store through @azure/identity-cache-persistence and restores the selected non-secret authentication record across GitHub Copilot app restarts.
  • Distinguishes authentication-required failures from operational errors, recovers from malformed records, retries failed legacy-cache cleanup, and deduplicates concurrent cold-start token requests.
  • Updates the public extension listing and in-canvas guidance to describe the GitHub Copilot app experience rather than Azure CLI or session restart steps.

The existing loopback binding, capability-token protection, and TextOnlyContent: false MCP configuration behavior remain unchanged.


Type of Contribution

  • New instruction file.
  • New prompt file.
  • New agent file.
  • New plugin.
  • New skill file.
  • New agentic workflow.
  • New canvas extension.
  • Update to existing instruction, prompt, agent, plugin, skill, workflow, or canvas extension.
  • Other (please specify):

Additional Notes

Validation completed:

  • Connector extension test suite: 103 tests passed.
  • npm run plugin:validate
  • npm run build

On 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.

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>
Copilot AI review requested due to automatic review settings July 20, 2026 20:10
@alexyaang
alexyaang requested a review from aaronpowell as a code owner July 20, 2026 20:10
@github-actions github-actions Bot added the canvas-extension PR touches canvas extensions label Jul 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread extensions/connector-namespaces/auth.mjs Outdated
Comment thread extensions/connector-namespaces/auth.mjs Outdated
Comment thread extensions/connector-namespaces/README.md Outdated
Comment thread extensions/connector-namespaces/README.md Outdated
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>
Copilot AI review requested due to automatic review settings July 20, 2026 20:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 17/17 changed files
  • Comments generated: 3
  • Review effort level: Medium

Comment thread extensions/connector-namespaces/auth.mjs
Comment thread extensions/connector-namespaces/test/README.md
Comment thread extensions/connector-namespaces/README.md Outdated
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>
Copilot AI review requested due to automatic review settings July 20, 2026 21:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 17/17 changed files
  • Comments generated: 2
  • Review effort level: Medium

Comment thread extensions/connector-namespaces/auth.mjs Outdated
Comment thread extensions/connector-namespaces/package.json Outdated
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>
Copilot AI review requested due to automatic review settings July 20, 2026 21:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 17/17 changed files
  • Comments generated: 1
  • Review effort level: Medium

Comment thread extensions/connector-namespaces/auth.mjs Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 20, 2026 21:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 17/17 changed files
  • Comments generated: 2
  • Review effort level: Medium

Comment thread extensions/connector-namespaces/auth.mjs
Comment thread extensions/connector-namespaces/test/README.md Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 20, 2026 22:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 single credential/accessToken. Reloading the canvas during sign-in (or opening it twice) can therefore authenticate two accounts concurrently; completion order can make one session report done while 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

Copilot AI review requested due to automatic review settings July 20, 2026 23:06
@codemillmatt
codemillmatt merged commit ecf0f5a into github:main Jul 20, 2026
10 of 11 checks passed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 session done; a Cancel request during either await still sees pending, marks the session cancelled, yet this continuation can write azure-auth-record.json (and authenticate() 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 while saveAuthRecord is 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();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

canvas-extension PR touches canvas extensions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants