Skip to content

Add auth-cache clear command#434

Open
beyondszine wants to merge 1 commit into
microsoft:mainfrom
beyondszine:feature/auth-cache-clear
Open

Add auth-cache clear command#434
beyondszine wants to merge 1 commit into
microsoft:mainfrom
beyondszine:feature/auth-cache-clear

Conversation

@beyondszine
Copy link
Copy Markdown
Contributor

Add a top-level auth-cache clear command that removes the Agent 365 CLI auth-token cache without touching the MSAL/WAM broker cache or triggering authenticated startup work before clearing.

why?
a365 cli stores token in cache & if it gets stale due to any reasons - the next runs just fails. Thus, auth-cache clear command can help users.

Add a top-level auth-cache clear command that removes the Agent 365 CLI auth-token cache without touching the MSAL/WAM broker cache or triggering authenticated startup work before clearing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 29, 2026 07:02
@beyondszine beyondszine requested review from a team as code owners May 29, 2026 07:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a new auth-cache clear CLI command to manage cached authentication tokens, along with related wiring, constants, and documentation updates.

Changes:

  • New AuthCacheCommand with a clear subcommand that deletes the CLI auth token cache file.
  • Program.cs registers the command and excludes it from pre-execution auth flow.
  • Documentation comments updated to reflect new cache paths; tests added for clear behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/Microsoft.Agents.A365.DevTools.Cli/Commands/AuthCacheCommand.cs New command implementing auth-cache clear.
src/Microsoft.Agents.A365.DevTools.Cli/Constants/CommandNames.cs Adds AuthCache constant.
src/Microsoft.Agents.A365.DevTools.Cli/Program.cs Registers command and skips auth pre-step for it.
src/Microsoft.Agents.A365.DevTools.Cli/Services/AuthenticationService.cs Updates cache location comment.
src/Microsoft.Agents.A365.DevTools.Cli/Services/MsalBrowserCredential.cs Updates cache location comment.
src/Tests/.../AuthCacheCommandTests.cs Adds unit tests for the new command.

Comment on lines +253 to +254
var isAuthCacheCommand = args.FirstOrDefault(arg => !arg.StartsWith("-")) == CommandNames.AuthCache;
if (!isHelpOrVersion && !isShowSecret && !isAuthCacheCommand)
Comment on lines +46 to +50
catch (Exception ex) when (ex is IOException or UnauthorizedAccessException or System.Security.SecurityException)
{
logger.LogError("Failed to delete {Path}: {Message}", path, ex.Message);
context.ExitCode = 1;
}

public void Dispose()
{
try { Directory.Delete(_cacheDirectory, recursive: true); } catch { }
Comment on lines +41 to +49
[Fact]
public async Task Clear_WhenCacheFilesDoNotExist_Succeeds()
{
var command = AuthCacheCommand.CreateCommand(_logger, _cacheDirectory);

var result = await command.InvokeAsync(["clear"]);

result.Should().Be(0);
}
@sellakumaran
Copy link
Copy Markdown
Contributor

@beyondszine , thanks for putting this together. The motivation is real (stale tokens breaking subsequent commands), but I'd like us to fix the root cause rather than add a user-facing command that papers over it.

The real bug

In AuthenticationService.GetAccessTokenAsync the cache key only includes userId when callers happen to pass one:

string cacheKey = string.IsNullOrWhiteSpace(tenantId)
    ? resourceUrl
    : $"{resourceUrl}:tenant:{tenantId}";
if (!string.IsNullOrWhiteSpace(userId))
    cacheKey = $"{cacheKey}:user:{userId}";

Many call sites don't thread userId through. So when a user runs az logout && az login as a different identity in the same tenant, the cache returns the previous identity's token — either silently running as the wrong user or producing a confusing 401. That is the symptom this PR is trying to mitigate.

Why a manual command isn't the right answer

a365 is built on top of azaz is our identity source of truth. Every legitimate scenario for "I want different/fresh credentials" already starts with an az action the CLI should be detecting:

Scenario What the user already does
Switch identity az login (different user)
Start clean az logout && az login
CI / scripted bootstrap az login --service-principal

Asking users to also learn a365 auth-cache clear teaches them about an internal token-cache file they shouldn't need to know exists, and trains a "clear cache and retry" reflex that hides real bugs (wrong tenant config, missing role assignment, revoked grant — none of which clearing the cache actually fixes).

What I'd like to see instead

  1. Make the cache key follow the active az identity. Resolve the current az UPN at command entry (we already have AzCliHelper and ResolveLoginHintFromCacheAsync) and include it unconditionally in every cache key. On mismatch, drop the stale entry — don't return it.
  2. Self-heal on parse failure. The catch at lines 191–194 currently logs a warning and leaves the corrupt file on disk. Call ClearTokenCacheAsync() (or rewrite just the bad entry) inside that catch so the next command isn't asking the user to do anything.
  3. One-shot retry on invalid_grant / AADSTS50173. When MSAL says the cached refresh material is dead, invalidate that entry and re-acquire interactively once before surfacing the error.
  4. Error copy. When auth genuinely can't recover, the message should point at az login — not a new a365 command. Example: "Your Azure CLI session looks stale. Run az login and re-run this command."

After (1)–(3), the failure mode that motivated this PR doesn't reach the user in the first place, and there's no manual command to invoke.

Suggested next step

Close this PR and open a new one against AuthenticationService covering the four points above. Happy to review.

Copy link
Copy Markdown
Contributor

@sellakumaran sellakumaran left a comment

Choose a reason for hiding this comment

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

See my comment in the PR.

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.

4 participants