WorkIQ MCP auth: UI-tier device-code flow (Phase 3 of #441)#443
Merged
Conversation
Phase 3 of #441. The UI tier (Blazor + CLI) drives the MSAL device-code flow against Entra, serializes the resulting cache, and publishes WorkIqAuthCacheUpdated to the agent. Both surfaces use the same flow so the Blazor server-rendered app needs no callback route or PKCE cookie — the user just types the displayed code into a browser tab. New shared library RockBot.UserProxy.WorkIqAuth contains the device-code orchestrator, settings, the expired-notification listener, and the auth message contracts (relocated from RockBot.Agent.McpBridge.Auth so both sides reference the same types). Blazor: WorkIqConnect.razor (NotStarted/InProgress/Success/Failed states), WorkIqReconnectBanner.razor, WorkIqAuthUiService (scoped per circuit). M365 pill in chat header opens a connect modal; banner reappears above the chat when the agent publishes WorkIqAuthExpired. CLI: `rockbot auth workiq` command. Spectre.Console renders the device code + URL; awaits MSAL polling; publishes cache; exits 0/130/78/1 by WorkIqAuthFlowException code. HostFactory.Build gains an optional configure delegate so only this command pulls in MSAL. Helm: Blazor deployment env vars (WorkIQ__TenantId/ClientId/Scopes/Authority) gated on workiq.enabled. No new values.yaml keys — reuses the block introduced in Phase 2. Out of scope: Phase 4 Entra registration + end-to-end smoke, Phase 5 re-consent polish. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Closes Phase 3 of #441. The UI tier (Blazor + CLI) drives the MSAL device-code flow against Entra, serializes the resulting cache, and publishes
WorkIqAuthCacheUpdatedto the agent. Out of scope here: Phase 4 (Entra app registration + end-to-end smoke), Phase 5 (re-consent polish).Summary
RockBot.UserProxy.WorkIqAuthholds the device-code orchestrator (WorkIqDeviceCodeFlow), settings (WorkIqClientSettings), the expired-notification listener (WorkIqAuthStatusListener), and the auth message contracts (WorkIqAuthCacheUpdated/Expired/Topics— relocated fromRockBot.Agent.McpBridge.Authso both sides reference the same types).WorkIqConnect.razorcovers the NotStarted/InProgress/Success/Failed states and a copy-code button.WorkIqReconnectBanner.razorappears above the chat header onWorkIqAuthExpired.WorkIqAuthUiServiceis scoped per circuit and bridges listener events to component re-renders. An "M365" pill in the chat header opens the connect modal.rockbot auth workiqrenders the device code + URL with Spectre.Console, polls until completion, publishes the cache, and exits with stable codes (0 success, 130 user-cancelled, 78 not-configured, 1 other).HostFactory.Buildgained an optionalconfiguredelegate so only this command pulls MSAL into the host's services.WorkIQ__TenantId/ClientId/Scopes/Authority) gated onworkiq.enabled. No newvalues.yamlkeys — reuses theworkiq.*block introduced in Phase 2.Test plan
dotnet build RockBot.slnxclean (0 errors)dotnet test RockBot.slnxclean across all 20 test projectsRockBot.UserProxy.WorkIqAuth.Tests(settings binding, listener event flow + dead-letter on malformed payload, flow rejects not-configured); 7 inRockBot.UserProxy.Blazor.Tests(UI state service transitions, dispose unsubscribes); 2 inRockBot.Cli.Tests(host factory wires the flow only when configured)helm templatewithworkiq.enabled=falseemits no WorkIQ env vars on Blazorhelm template --set workiq.enabled=true ...emits the four conditional env vars on the Blazor deploymentType relocation note
WorkIqAuthCacheUpdated,WorkIqAuthExpired, andWorkIqAuthTopicsmoved fromRockBot.Agent.McpBridge.Auth→RockBot.UserProxy.WorkIqAuthso the UI tier doesn't depend on the agent project. Phase 2's agent files added one newusing RockBot.UserProxy.WorkIqAuth;directive; behavior is unchanged.🤖 Generated with Claude Code