Repository navigation
Azure: scoped delegation in the Share panel no longer fails with 503 - #182
Merged
Keith McGrane (Keithland89) merged 1 commit intoOct 23, 2026
Merged
Keith McGrane (Keithland89) merged 1 commit into
Keith McGrane (Keithland89) merged 1 commit into
Conversation
With org-scoped access on, every /api/delegations request failed at once with 503 DatabaseUnavailable, even with the database online. mssql's ConnectionPool deep-copies its config with rfdc, which copies only own enumerable properties into plain objects, so the getToken that ManagedIdentityCredential defines on its prototype was lost. tedious then refused the copy: 'The "config.authentication.options.credential" property must be an instance of the token credential class.' That isn't an error a resuming database gives, so the store gave up on the first attempt. SqlScopeStore now hands the driver an object with a getToken of its own that calls the credential it uses, injected or the managed identity, and that survives the copy. The new test drives the real mssql and tedious with a credential whose getToken is on its class's prototype. A connector that refuses keeps it offline: no name lookup, no socket. It fails without the fix and passes with it. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
4 of 5 tasks
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.
Summary
Row 32 of 0.6.8 (finding 41). On Azure with org-scoped access on, every
/api/delegationsrequest failed at once with 503DatabaseUnavailable, "Couldn't reach the Analytics Hub database. Try again in a minute.", even with the database online. So the Share panel's scoped delegation couldn't show, give, take back or approve scopes. A test install on 0.6.8-rc.2 showed it on 22 Oct, and its web app logged:Cause.
SqlScopeStorehanded mssql its credential, aManagedIdentityCredentialby default, asauthentication.options.credential(azure/web/src/scope-store.js:35). The versions below are the lockfile's, the same at every installer-v0.6.* tag and on main.ConnectionPoolconstructor deep-copies its config with rfdc 1.4.1 (node_modules/mssql/lib/base/connection-pool.js:56,this.config = clone(config)). rfdc copies only own enumerable properties, into plain objects. So the copy losesgetToken, which the credential's class defines on its prototype.isTokenCredentialfrom @azure/core-auth 1.11.0, and throws the TypeError above (node_modules/tedious/lib/connection.js:313–315).RESUMINGpattern (scope-store.js:15), soconnect()gives up on attempt 1 (:44), andunavailable()returns the 503 (:132–135).Fix (
scope-store.js:21–24). The store hands the driver{ getToken: (scopes, options) => source.getToken(scopes, options) }, wheresourceis the injected credential or theManagedIdentityCredential. rfdc copies a function in an own property by reference, sogetTokensurvives the copy, andisTokenCredentialaccepts the object. The identity, the token scope and the pool settings are unchanged.Why CI missed it. The store's existing test (
azure/web/test/delegations.test.js:285–316) stubsConnectionPool, so nothing copies the config, and it checks only the auth type.Reach. Only
DelegationServiceuses the store (azure/web/src/delegations.js:31), and nothing else in the repo uses mssql. The store hasn't changed since #31 (f08be05), which every tag from installer-v0.6.0 contains, so the fault has been in the web app since 0.6.0. But the app couldn't reach it before 0.6.8-rc.2:config.host === "azure" && config.access?.rlsOrgAttribute(app/src/components/share-panel.tsx:49, the same at installer-v0.6.7). Only that component,share-delegations.tsx, calls/api/delegations./app.config.json(azure/web/src/server.js:35–37) sendsaccess: publicAccess(config.access).publicAccess(:109–112) keeps onlygroupId,groupName,contactandrequestUrl.rlsOrgAttributetopublicAccess(server.js:112–114there).So released versions, 0.6.7 included, could reach the fault only by calling the API directly, and 0.6.7 needs no Known issue.
Scope
Parts affected (installer / app / Fabric notebooks and pipeline / Azure infra, jobs or web / core / Power BI models): Azure web (
azure/web) only.Source contracts, optional inputs, install record or deployed item names changed: none.
Files:
azure/web/src/scope-store.js: theSqlScopeStoreconstructor (:21–24). Nothing else changed.azure/web/test/delegations.test.js: one new test (:318–356). The stubbed test at:285–316is unchanged.CHANGELOG.md: one**Fixed:**entry, last under## Unreleased. It comes after App: start on the last 12 weeks for a large tenant #177's**Changed:**entry, just before## Analytics Hub installer 0.6.8-rc.2 (unreleased)(now:267).Doc lines changed: only
CHANGELOG.md:255–265. No README ordocs/page describes the fault.azure/web/README.md:13says the delegation routes write as the managed identity, which still holds.Validation
python -B -m pytest tests -qand recorded results below.npm test(andnpm run typecheckfor the installer) in each changed Node project..pbitfiles changed, documented the rebuild method and Desktop refresh / visual checks. (N/A: no.pbitchanges.)Results, skipped checks and limitations:
The new test drives the real mssql and tedious, not the stub:
RecordingPoolextends mssql'sConnectionPooland gives tedious aconnectorthat refuses ("no sockets in tests"). So nothing looks up a name or opens a socket. The server issql.example.invalidas a backstop.getTokenon its prototype, likeManagedIdentityCredential.console.warnis restored afterwards.connect()still ends in 503, because the connector refuses.getTokenthat calls the test's credential and returns its token.ManagedIdentityCredential, is taken the same way. That credential is never asked for a token.It takes about 0.35 s.
Fail before, pass after. All run in
azure/webafternpm.cmd ci(node v24.19.0, npm 11.17.0):node --test --test-name-pattern="survives mssql copying" test/delegations.test.js:SQL connection failed: The "config.authentication.options.credential" property must be an instance of the token credential class.npm.cmd test:Not run here:
python -B -m pytest tests -q, and the app and installer suites, which this PR doesn't touch. This PC is shared with live speed tests, so CI runs them. I did check the new CHANGELOG paragraph againsttests/test_parked_ideas.py's front-door patterns, with no hits.git diff --checkis clean. Nothing calls live Azure, Entra, SQL or a tenant.Follow-up, not in this PR: the 503 says "Try again in a minute." for every connection failure except a resuming database, where waiting won't help. Its wording could be a follow-up.
Compatibility
images.tag(installer/src/steps/azure/index.js:94). Scoped delegation in the Share panel then works with org-scoped access on.