Structural auth guardrails so agents never trigger sign-in silently#173
Open
TomProkop wants to merge 1 commit into
Open
Structural auth guardrails so agents never trigger sign-in silently#173TomProkop wants to merge 1 commit into
TomProkop wants to merge 1 commit into
Conversation
Fixes the recurring failure mode where an AI coding agent driving txc CLI/MCP gets confused about Profile/Connection/Credential, invents new profiles/connections speculatively, or ends up stuck on an unattended device-code prompt when a token expires. Grounded in real usage from the alm-lab checkpoint scripts, which show the golden pattern: sign-in is always a deliberate human action (--device-code passed explicitly, never relying on auto-fallback), and existing profiles/connections are always listed before creating new ones. No agent-harness environment-variable detection is used anywhere — the fixes are purely structural and apply uniformly to any caller. Tier 1 (structural, safety-critical): - AuthLoginCliCommand: remove the silent browser-unavailable -> device-code auto-fallback. Now fails fast with a clear message instead of ever starting an unattended device-code flow. - DataverseAccessTokenService.AcquirePublicClientSilentAsync: remove the automatic interactive/device-code re-authentication attempted on MsalUiRequiredException during token refresh (the exact "token expires mid-session" case reported) — now always throws immediately with a manual-sign-in message. - HeadlessAuthRequiredException.BuildMessage: lead with the manual-human-sign-in rule before headless remedy details. - ConfigurationResolver / ProfileValidateCliCommand: extend "no profile" error messages with a list-before-create nudge (config profile list / config connection list). - Bake the Credential/Connection/Profile model, list-before-create, and manual-sign-in rules directly into --help text for AuthCliCommand, ProfileCliCommand, ConnectionCliCommand, ProfileCreateCliCommand. - CliSubprocessRunner: extract BuildStartInfo so the MCP-forced TXC_NON_INTERACTIVE=1 contract has direct unit test coverage (CliSubprocessRunnerTests) instead of relying only on indirect integration coverage. Tier 2 (optional documentation reinforcement): - docs/profiles-and-authentication.md: add a "Sign-in is manual" callout for agent-adjacent workflows. - MCP troubleshooting-patterns skill: add auth-failure anti-patterns (don't self-sign-in, don't create profiles speculatively). - CopilotInstructionsManager: add a short Authentication section to the generated copilot-instructions.md. Tests: 701/701 passing (698 pre-existing + 3 new CliSubprocessRunner regression tests). Full solution builds with 0 errors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.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.
Problem
AI coding agents driving
txcCLI/MCP repeatedly get confused about Profile/Connection/Credential when a token expires or no credential exists, invent profiles/connections speculatively, or end up stuck on an unattended device-code prompt no one is watching, instead of stopping and asking the user to sign in interactively.Approach
Grounded in real usage from the
alm-labcheckpoint scripts, which show the golden pattern already used by humans/scripts: sign-in is always a deliberate action (--device-codepassed explicitly, never relying on auto-fallback), and existing profiles/connections are always listed before creating new ones.No agent-harness environment-variable detection is used anywhere — every fix is structural (change what the CLI does) or message/help-driven (steer whoever/whatever is calling), so it applies uniformly to humans, known agents, and unknown future agents alike.
Changes
Tier 1 — structural, safety-critical:
AuthLoginCliCommand: removed the silent browser-unavailable → device-code auto-fallback. Fails fast with a clear message instead of ever starting an unattended device-code flow.DataverseAccessTokenService.AcquirePublicClientSilentAsync: removed the automatic interactive/device-code re-authentication attempted onMsalUiRequiredExceptionduring token refresh — the literal "token expires mid-session" case reported. Now always throws immediately with a manual-sign-in message.HeadlessAuthRequiredException.BuildMessage: leads with the manual-human-sign-in rule before headless remedy details.ConfigurationResolver/ProfileValidateCliCommand: extended "no profile" error messages with a list-before-create nudge (config profile list/config connection list).--helptext forAuthCliCommand,ProfileCliCommand,ConnectionCliCommand,ProfileCreateCliCommand.CliSubprocessRunner: extractedBuildStartInfoso the MCP-forcedTXC_NON_INTERACTIVE=1contract has direct unit test coverage (newCliSubprocessRunnerTests) instead of relying only on indirect integration coverage.Tier 2 — optional documentation reinforcement:
docs/profiles-and-authentication.md: added a "Sign-in is manual" callout for agent-adjacent workflows.troubleshooting-patterns.mdskill: added auth-failure anti-patterns (don't self-sign-in, don't create profiles speculatively).CopilotInstructionsManager: added a short Authentication section to the generatedcopilot-instructions.md.Also verified (no change needed): the
--urlone-liner bootstrap path already callsIHeadlessDetector.EnsureKindAllowed(CredentialKind.InteractiveBrowser)before attempting interactive sign-in and is only reachable via an explicit human-supplied--urlflag — consistent with the "manual, deliberate" principle.Testing
dotnet build TALXIS.CLI.sln— 0 errors.dotnet test— 701/701 passing (698 pre-existing + 3 newCliSubprocessRunnerTests).Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com