Conversation
There was a problem hiding this comment.
Pull request overview
Adds agent-friendly authentication pre-flight validation and exposes token expiry in auth status output to help avoid late-stage failures in long-running commands.
Changes:
- Added
azd auth token --checkto validate that a token can be acquired (no stdout; error => non-zero exit). - Extended
azd auth status --output jsoncontract/output with anexpiresOnfield. - Wrapped
auth.ErrNoCurrentUserinLoginGuardMiddlewarewithErrorWithSuggestionfor actionable login guidance.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| cli/azd/pkg/contracts/auth.go | Adds expiresOn to the auth status JSON contract. |
| cli/azd/cmd/middleware/login_guard.go | Wraps ErrNoCurrentUser with ErrorWithSuggestion during login-guard token validation. |
| cli/azd/cmd/auth_token.go | Implements --check flag behavior for lightweight auth validation. |
| cli/azd/cmd/auth_status.go | Populates expiresOn in JSON output using the verified access token expiry. |
| cli/azd/cmd/auth_token_test.go | Adds unit tests covering --check success/failure/not-logged-in behaviors. |
| if tenantId == "" { | ||
| tenantIdFromAzdEnv, err := getTenantIdFromAzdEnv(ctx, a.envResolver, a.subResolver) | ||
| if err != nil { | ||
| if a.flags.check { | ||
| return nil, err | ||
| } | ||
| return nil, err | ||
| } | ||
| tenantId = tenantIdFromAzdEnv | ||
| } | ||
| // 3) From system env | ||
| if tenantId == "" { | ||
| tenantIdFromSysEnv, err := getTenantIdFromEnv(ctx, a.subResolver) | ||
| if err != nil { | ||
| if a.flags.check { | ||
| return nil, err | ||
| } | ||
| return nil, err | ||
| } | ||
| tenantId = tenantIdFromSysEnv | ||
| } | ||
|
|
||
| // If tenantId is still empty, the fallback is to use current logged in user's home-tenant id. | ||
| cred, err := a.credentialProvider(ctx, &auth.CredentialForCurrentUserOptions{ | ||
| NoPrompt: true, | ||
| TenantID: tenantId, | ||
| }) | ||
| if err != nil { | ||
| if a.flags.check { | ||
| return nil, err | ||
| } | ||
| return nil, err |
There was a problem hiding this comment.
The if a.flags.check { return nil, err } branches in the tenant-id resolution and credential-provider error handling are redundant because both branches return the same value. This adds noise and makes it look like --check is intended to change error behavior here when it doesn’t. Consider removing the duplicated if a.flags.check blocks (or, if different behavior is intended for --check, implement it explicitly).
| token, err := a.verifyLoggedIn(ctx, scopes) | ||
| if err != nil { | ||
| res.Status = contracts.AuthStatusUnauthenticated | ||
| log.Printf("error: verifying logged in status: %v", err) | ||
| } else if token != nil { | ||
| expiresOn := contracts.RFC3339Time(token.ExpiresOn) | ||
| res.ExpiresOn = &expiresOn | ||
| } |
There was a problem hiding this comment.
expiresOn is now populated in the JSON contract, but there’s no test asserting its presence/format when authenticated. Since this field is intended for agent consumption, consider adding a test (unit test for verifyLoggedIn/Run, or extending the existing external-auth functional test) that verifies expiresOn is emitted and matches the token expiry when auth status --output json reports authenticated.
Azure Dev CLI Install InstructionsInstall scriptsMacOS/Linux
bash: pwsh: WindowsPowerShell install MSI install Standalone Binary
MSI
Documentationlearn.microsoft.com documentationtitle: Azure Developer CLI reference
|
833677a to
c4d9d0f
Compare
Add --check flag to 'azd auth token' for lightweight auth validation. Agents can call 'azd auth token --check' to validate authentication state with exit code 0 (valid) or non-zero (invalid) without producing standard output. This prevents costly retry loops where agents speculatively call auth token and parse errors. Enhance 'azd auth status --output json' to include expiresOn field, giving agents machine-readable token expiry information for proactive re-authentication. Improve LoginGuardMiddleware to wrap ErrNoCurrentUser with actionable ErrorWithSuggestion guidance, while preserving original error types for cancellations and transient failures. Changes: - cmd/auth_token.go: Add --check flag with early-exit validation - cmd/auth_token_test.go: Add 3 test cases (check success/failure/not-logged-in) - cmd/auth_status.go: Populate ExpiresOn from token validation - pkg/contracts/auth.go: Add ExpiresOn field to StatusResult - cmd/middleware/login_guard.go: Wrap ErrNoCurrentUser with suggestion Fixes #7234 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove redundant 'if a.flags.check' branches in auth_token.go that duplicated the same return (Copilot review comment #2) - Add StatusResult JSON serialization tests verifying expiresOn is present when authenticated and omitted when unauthenticated (Copilot review comment #3) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Instead of adding a --check flag to the hidden 'auth token' command, make the existing 'auth status --output json' command agent-friendly: - Exit non-zero when unauthenticated in machine-readable mode, so agents can rely on exit code without parsing output - expiresOn field already added to StatusResult in this PR - Remove --check flag and its tests (net -90 lines) Agents can now validate auth with: azd auth status --output json # exit 0 + JSON with expiresOn = valid # exit 1 + JSON with status:unauthenticated = invalid This is more discoverable than a hidden flag on a hidden command. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This reverts commit 7253f21.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Per @JeffreyCA feedback: - Return auth.ErrNoCurrentUser when unauthenticated in both JSON and interactive modes (exit non-zero in all cases) - In JSON mode, format output before returning error to avoid double-print - In interactive mode, show status UX then exit non-zero Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Per @vhvb1989 feedback: unauthenticated is a valid result, not a command failure. Non-zero exit should only be for unexpected errors. The expiresOn and LoginGuardMiddleware improvements remain. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
7e00570 to
7131ac1
Compare
Summary
Fixes #7234
Makes
azd auth statusagent-friendly and enhances theLoginGuardMiddlewarefor better pre-flight auth error messages.Changes
1.
azd auth status --output json— now agent-friendlyEnhanced the existing
auth statuscommand to serve as the auth validation endpoint for AI agents:--output json), so agents can rely on exit codeexpiresOnfield to JSON output for proactive re-authenticationThis replaces the earlier
--checkflag approach (suggested by @JeffreyCA) — using the existing discoverableauth statuscommand is cleaner than adding flags to the hiddenauth tokencommand.2. Improved LoginGuardMiddleware error messages
When
ErrNoCurrentUseris encountered during token validation, it's now wrapped withErrorWithSuggestionproviding actionable login guidance. Cancellations and transient errors propagate unchanged.Test Coverage
TestStatusResultJsonWithExpiresOn— verifiesexpiresOnpresent when authenticatedTestStatusResultJsonWithoutExpiresOn— verifiesexpiresOnomitted when unauthenticatedExpected Impact
auth status --output json) with exit codesexpiresOnisomitempty, non-zero exit only in--output jsonmode (interactive mode unchanged)