Repository navigation
Conversation
|
⏳ DRAFT
What to do
Review readiness checklist
✅ 4/4 boxes ticked. This pull request was already a draft. Its draft status will be preserved after every issue above is resolved. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
…t refusal
The Kiro desktop refresh endpoint answers a dead refresh token with HTTP
401 and a bare {"message":"Bad credentials"} body, without an OAuth error
code, so the account was never marked needsReauth and stayed healthy while
every refresh failed. Classify exactly that desktop 401 reply under the
fixed code bad_credentials so the existing generation-fenced quarantine
path applies. AWS SSO refreshes, other 401 messages, other statuses, 5xx
and network failures stay retryable.
Assisted-by: Claude Opus 5.5 (Claude Code)
7fab71e to
2b088c7
Compare
|
Carried onto an upstream branch in #7062 (with a Co-authored-by trailer) so the repository CI can run. It is held there for the security review that MAINTAINERS.md requires for authentication changes. Leaving this PR open until that review concludes. |
…top Bad credentials (#7053, #7054) (#7062) * fix(kiro): accept authorized social device grants Carries #7053. Preserve token, profile, principal, and HTTP validation. Co-authored-by: Veritas-7 <234569343+Veritas-7@users.noreply.github.com> * fix(kiro): quarantine exact desktop bad-credentials refusals Carries #7054. Keep AWS SSO and other status/message pairs retryable. Co-authored-by: Veritas-7 <234569343+Veritas-7@users.noreply.github.com> * fix(chatgpt): preserve launcher when app inspection fails Carries #7055. Report unknown inspection state and refuse an unconfirmed restart. Co-authored-by: lcxhh <lcxhh521@gmail.com> * fix(proxy): bound SOCKS5 TLS handshake lifetime Carries #7056. Clear deadline and listeners on every TLS handshake exit while keeping certificate verification. Co-authored-by: lcxhh <lcxhh521@gmail.com> * docs: triage exceeded-retry-limit 429 errors Carries #6925. Align refresh release conditions and the resolved credit rediscovery reference with current dev. Co-authored-by: Howard-Jerry <197214646+Howard-Jerry@users.noreply.github.com> --------- Co-authored-by: JUN <243035832+lidge-jun@users.noreply.github.com> Co-authored-by: Veritas-7 <234569343+Veritas-7@users.noreply.github.com> Co-authored-by: lcxhh <lcxhh521@gmail.com> Co-authored-by: Howard-Jerry <197214646+Howard-Jerry@users.noreply.github.com> Co-authored-by: jun <jun@juns-Mac-Studio.local>
Summary
When a Kiro desktop-auth account (social login, no registered AWS SSO client) holds a dead refresh token, the account is never flagged for reauthentication. It stays healthy and logged in while every refresh fails.
The desktop refresh endpoint
POST https://prod.us-east-1.auth.desktop.kiro.dev/refreshTokenanswers an invalid refresh token with HTTP 401 and a body whose only key ismessage:{"message":"Bad credentials"}(observed 2026-10-13). It has no OAutherrorfield.kiroTokenRefreshErrorinsrc/oauth/kiro.tsonly readspayload.erroragainstKIRO_TERMINAL_REFRESH_ERRORS, sooauthErrorstaysundefined.terminal()insrc/oauth/index.tstreats aKiroTokenRefreshErroras terminal only when a 400/401 carries anoauthError, so the account is never markedneedsReauth.The fix is narrow. For the desktop endpoint only (not the AWS SSO OIDC refresh), HTTP 401 together with
message === "Bad credentials"(exact match) is classified as a terminal grant refusal. It is surfaced under the fixed codebad_credentials, and the raw upstream text is never echoed. The existing generation-fenced quarantine path then marks the rejected generationneedsReauth, exactly as it does forinvalid_grant. Nothing else becomes terminal: any other 401 message, the same message with another status, the same pair from the AWS SSO endpoint, 5xx and network failures all stay retryable. The #6716 refresh-attention behavior for AWS SSOinvalid_requestis unchanged.One interaction worth calling out: in
refreshKiroToken, an AWS SSO 400 can fall back to a rotated local kiro-cli credential, and that recovery may use the desktop endpoint. If the recovery attempt itself gets the desktop 401Bad credentials, the account is now quarantined instead of staying retryable. At that point both the stored token and the local CLI token have been refused, so reauthentication is the only way forward. A dedicated regression covers this path: the AWS SSO 400 is followed by the desktop 401Bad credentials, and the test asserts the request order (OIDC, then desktop),OAuthLoginRequiredErrorand storedneedsReauth: true.Changed files:
src/oauth/kiro.ts: recognize the exact desktop 401Bad credentialsreply inkiroTokenRefreshError.tests/oauth/oauth-kiro-refresh-attention.test.ts: one positive regression plus one CLI-recovery regression (desktop 401Bad credentials→OAuthLoginRequiredError, storedneedsReauth: true,loggedIn: false, a single request to the desktop endpoint) and three negative cases (desktop 401 with another message, desktop 400Bad credentials, AWS SSO 401Bad credentials→ not quarantined).structure/providers-and-adapters.md: one sentence on the Kiro refresh contract paragraph, kept within the file's line budget.Verification
Base:
devate2886a64a(rebased). Earlier figures were measured on582589c23/60752ec3c. Tests were run with Bun 1.4.2 (the runtime the package ships); CONTRIBUTING pins 1.4.3 for the suite runner, so CI is the authoritative run.bun test ./tests/oauth/oauth-kiro-refresh-attention.test.ts: 27 pass, 0 fail (22 existing + 5 new).src/oauth/kiro.tsaltered:Bad credentialscase and the CLI-recovery case).desktop 401 with another message).AWS SSO 401 Bad credentials).desktop 400 Bad credentials).e2886a64a:bun test ./tests/oauth/oauth-kiro-refresh-attention.test.ts ./tests/providers/kiro/kiro-oauth.test.ts ./tests/server/server-kiro-oauth-401-replay.test.ts: 92 pass, 0 fail;bun test ./tests/oauth/oauth-refresh.test.ts: 67 pass, 0 fail;bun run typecheckandbun run structure:checkpass.bun run typecheck: passed.bun run structure:check: passed. The doc file stays at its 600-line budget.bun run privacy:scan: passed.git diff --check: clean.I did not run the full local suite (
bun run test). The change is confined to one error classifier, and the focused files above cover Kiro refresh, refresh attention, the generic OAuth refresh lock and the 401 replay path. Required CI on the PR head still has to pass.Checklist
src/oauth/index.ts.structure/providers-and-adapters.mdKiro refresh paragraph now records the desktopBad credentialsverdict.maintainer-sponsored) per CONTRIBUTING.🤖 Generated with Claude Code
Review readiness checklist
This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:
Required local validation passed; commands, results, and any full-suite exception are documented.
I pushed my PR to a recent dev commit (at most 10 behind; a maintainer may still ask for the exact tip before merge).
I resolved all correct Codex and CodeRabbit findings.
My PR is ready for review.
Summary by CodeRabbit