Skip to content

fix(self-update): use WorkloadIdentityCredential on AKS (not ManagedIdentityCredential) - #116

Merged
rbuergi merged 1 commit into
mainfrom
fix/selfupdate-workload-identity
Jun 29, 2026
Merged

rbuergi merged 1 commit into
mainfrom
fix/selfupdate-workload-identity

Conversation

@rbuergi

@rbuergi rbuergi commented Jun 29, 2026 •

Copy link
Copy Markdown
Contributor

Completes the operational self-update install (follows #110). AcrTagLister used ManagedIdentityCredential (IMDS) when AZURE_CLIENT_ID was set — but the portal's UAMI is federated (workload identity), not VMSS-assigned, so IMDS returns no token and every self-update poll failed ([SelfUpdate] check failed).

Fix: detect AKS workload identity by AZURE_FEDERATED_TOKEN_FILE (injected by the WI webhook) and use WorkloadIdentityCredential, which exchanges the projected SA token for an AAD token. Falls back to user-assigned MI (VMSS/IMDS) when only AZURE_CLIENT_ID is set, else the dev chain.

Verified live on client-i with the now-provisioned: portal UAMI memexaks-portal-mi + AcrPull on meshweaver, the client-i:memex-portal-sa federated credential, and the memex-portal-sa ServiceAccount + get/patch RBAC. The poller authenticates and lists ACR tags with 0 errors (canPatch=True).

Must merge so future images the self-updater rolls to keep the fix.

🤖 Generated with Claude Code

…dentityCredential

AcrTagLister authenticated to ACR with ManagedIdentityCredential (IMDS) whenever AZURE_CLIENT_ID
was set. But the portal's UAMI is FEDERATED (workload identity), not assigned to the node VMSS, so
IMDS returns no token → every self-update poll failed ("[SelfUpdate] check failed") and no install
could ever discover an update. Detect AKS workload identity by AZURE_FEDERATED_TOKEN_FILE (injected
by the WI webhook alongside AZURE_CLIENT_ID/TENANT_ID) and use WorkloadIdentityCredential, which
exchanges the projected service-account token for an AAD token. Verified on atioz: with the portal
UAMI + AcrPull + the SA federated credential + the memex-portal-sa ServiceAccount, the poller now
authenticates and lists ACR tags with zero errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 3)

1 173 tests  ±0   1 173 ✅ +1   4m 58s ⏱️ -37s
   11 suites ±0       0 💤 ±0 
   11 files   ±0       0 ❌  - 1 

Results for commit e2c75cf. ± Comparison against base commit acac76c.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 1)

969 tests  +130   968 ✅ +132   4m 17s ⏱️ +17s
 12 suites ±  0     1 💤  -   1 
 12 files   ±  0     0 ❌  -   1 

Results for commit e2c75cf. ± Comparison against base commit acac76c.

This pull request removes 13 and adds 143 tests. Note that renamed tests count towards both.
MeshWeaver.Hosting.Monolith.Test.CircuitContextIsolationTest ‑ CircuitContext_DoesNotLeakAnotherUserAcrossAnAsyncLocalHop
MeshWeaver.Hosting.Monolith.Test.FileSystemStreamProviderTests ‑ GetStreamAsync_ExistingFile_ReturnsStream
MeshWeaver.Hosting.Monolith.Test.FileSystemStreamProviderTests ‑ GetStreamAsync_NonExistentFile_ReturnsNull
MeshWeaver.Hosting.Monolith.Test.FileSystemStreamProviderTests ‑ ProviderType_ReturnsFileSystem
MeshWeaver.Hosting.Monolith.Test.FileSystemStreamProviderTests ‑ WriteStreamAsync_CreatesDirectory
MeshWeaver.Hosting.Monolith.Test.FileSystemStreamProviderTests ‑ WriteStreamAsync_CreatesFile
MeshWeaver.Hosting.Monolith.Test.LinkedInProfileLayoutAreaTest ‑ LinkedInProfile_NodeType_CompilesAndRendersOverview
MeshWeaver.Hosting.Monolith.Test.MeshNodeCompilationIntegrationTest ‑ CompileFailsWhenSourceCodeIsInvalid
MeshWeaver.Hosting.Monolith.Test.MeshNodeCompilationIntegrationTest ‑ CompileWithMultipleSourceLocationsPullsInExternalCode
MeshWeaver.Hosting.Monolith.Test.MeshNodeCompilationIntegrationTest ‑ CompilesSimpleNodeTypeWithDefaultSources
…
MeshWeaver.Hosting.Monolith.Test.AgentPickerProjectionPartitionedTest ‑ PartitionedPath_ObserveAgents_FromHostedSubHub_PopulatesCombobox
MeshWeaver.Hosting.Monolith.Test.AgentPickerProjectionPartitionedTest ‑ PartitionedPath_ObserveAgents_PopulatesCombobox
MeshWeaver.Hosting.Monolith.Test.AgentPickerProjectionPartitionedTest ‑ PartitionedPath_ObserveModels_PopulatesCombobox
MeshWeaver.Hosting.Monolith.Test.AgentSyncedQueryFromHostedHubTest ‑ HostedSubHub_GetQuery_AgentDropdownNamesAreNonEmpty
MeshWeaver.Hosting.Monolith.Test.AgentSyncedQueryFromHostedHubTest ‑ HostedSubHub_GetQuery_ReturnsAgentsAndModels
MeshWeaver.Hosting.Monolith.Test.BrokenNodeTypeAccessTest ‑ AccessingInstance_OfNonCompilingNodeType_AnswersTerminalError_NotSilence
MeshWeaver.Hosting.Monolith.Test.CessionLayoutAreaTest ‑ BusinessRulesDoc_RelativeReference_ResolvesToMotorXL
MeshWeaver.Hosting.Monolith.Test.CessionLayoutAreaTest ‑ Cession_Trace_HubConfiguration
MeshWeaver.Hosting.Monolith.Test.CessionLayoutAreaTest ‑ MotorXL_LayoutArea_ReturnsContent
MeshWeaver.Hosting.Monolith.Test.CessionLayoutAreaTest ‑ MotorXL_Overview_ShouldRender
…

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 2)

 12 files  ±0   12 suites  ±0   6m 6s ⏱️ + 1m 40s
849 tests ±0  848 ✅ ±0  1 💤 ±0  0 ❌ ±0 
876 runs  ±0  875 ✅ ±0  1 💤 ±0  0 ❌ ±0 

Results for commit e2c75cf. ± Comparison against base commit acac76c.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 0)

2 230 tests  ±0   2 225 ✅ ±0   6m 53s ⏱️ - 1m 28s
   12 suites ±0       5 💤 ±0 
   12 files   ±0       0 ❌ ±0 

Results for commit e2c75cf. ± Comparison against base commit acac76c.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results

   47 files  ±  0     47 suites  ±0   22m 15s ⏱️ -8s
5 221 tests +130  5 214 ✅ +133  7 💤  - 1  0 ❌  - 2 
5 248 runs  +130  5 241 ✅ +133  7 💤  - 1  0 ❌  - 2 

Results for commit e2c75cf. ± Comparison against base commit acac76c.

This pull request removes 13 and adds 143 tests. Note that renamed tests count towards both.
MeshWeaver.Hosting.Monolith.Test.CircuitContextIsolationTest ‑ CircuitContext_DoesNotLeakAnotherUserAcrossAnAsyncLocalHop
MeshWeaver.Hosting.Monolith.Test.FileSystemStreamProviderTests ‑ GetStreamAsync_ExistingFile_ReturnsStream
MeshWeaver.Hosting.Monolith.Test.FileSystemStreamProviderTests ‑ GetStreamAsync_NonExistentFile_ReturnsNull
MeshWeaver.Hosting.Monolith.Test.FileSystemStreamProviderTests ‑ ProviderType_ReturnsFileSystem
MeshWeaver.Hosting.Monolith.Test.FileSystemStreamProviderTests ‑ WriteStreamAsync_CreatesDirectory
MeshWeaver.Hosting.Monolith.Test.FileSystemStreamProviderTests ‑ WriteStreamAsync_CreatesFile
MeshWeaver.Hosting.Monolith.Test.LinkedInProfileLayoutAreaTest ‑ LinkedInProfile_NodeType_CompilesAndRendersOverview
MeshWeaver.Hosting.Monolith.Test.MeshNodeCompilationIntegrationTest ‑ CompileFailsWhenSourceCodeIsInvalid
MeshWeaver.Hosting.Monolith.Test.MeshNodeCompilationIntegrationTest ‑ CompileWithMultipleSourceLocationsPullsInExternalCode
MeshWeaver.Hosting.Monolith.Test.MeshNodeCompilationIntegrationTest ‑ CompilesSimpleNodeTypeWithDefaultSources
…
MeshWeaver.Hosting.Monolith.Test.AgentPickerProjectionPartitionedTest ‑ PartitionedPath_ObserveAgents_FromHostedSubHub_PopulatesCombobox
MeshWeaver.Hosting.Monolith.Test.AgentPickerProjectionPartitionedTest ‑ PartitionedPath_ObserveAgents_PopulatesCombobox
MeshWeaver.Hosting.Monolith.Test.AgentPickerProjectionPartitionedTest ‑ PartitionedPath_ObserveModels_PopulatesCombobox
MeshWeaver.Hosting.Monolith.Test.AgentSyncedQueryFromHostedHubTest ‑ HostedSubHub_GetQuery_AgentDropdownNamesAreNonEmpty
MeshWeaver.Hosting.Monolith.Test.AgentSyncedQueryFromHostedHubTest ‑ HostedSubHub_GetQuery_ReturnsAgentsAndModels
MeshWeaver.Hosting.Monolith.Test.BrokenNodeTypeAccessTest ‑ AccessingInstance_OfNonCompilingNodeType_AnswersTerminalError_NotSilence
MeshWeaver.Hosting.Monolith.Test.CessionLayoutAreaTest ‑ BusinessRulesDoc_RelativeReference_ResolvesToMotorXL
MeshWeaver.Hosting.Monolith.Test.CessionLayoutAreaTest ‑ Cession_Trace_HubConfiguration
MeshWeaver.Hosting.Monolith.Test.CessionLayoutAreaTest ‑ MotorXL_LayoutArea_ReturnsContent
MeshWeaver.Hosting.Monolith.Test.CessionLayoutAreaTest ‑ MotorXL_Overview_ShouldRender
…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant