Repository navigation
Conversation
|
This PR doesn't fully meet our contributing guidelines and PR template. What needs to be fixed:
Please edit this PR description to address the above within 72 hours, or it will be automatically closed. If you believe this was flagged incorrectly, please let a maintainer know. |
pcomans
force-pushed
the
auth-code-login
branch
from
October 29, 2026 21:35
47bd8aa to
932447e
Compare
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.
OpenCode signs in to Vercel using the authorization-code grant with PKCE and a temporary loopback callback, then asks the user to confirm the team billed for AI Gateway inference. Access and rotating refresh tokens stay in the credential store; requests use the selected team's OAuth access token directly.
This is an alternative to the device-code implementation in #5. It includes the shared setup lifecycle and client fixes reviewed there, with the device polling replaced by browser authorization and a scoped local listener. No Gateway API keys are created. Existing credentials retain their original OAuth client binding during refresh.
The callback validates state and an issuer when supplied, rejects unrelated requests, and releases its listener when the attempt completes or is cancelled. CLI and desktop use the same callback mechanism. Remote clients need a browser on the server's machine or an explicit tunnel.
Validation passed 190 distinct tests across provider, core, CLI, TUI, client-contract, and built browser suites; all 35 repository checks and the official core TypeScript check passed. Client generation is current. A small existing UI issue is fixed: authorization-code instructions no longer appear as a device confirmation code, while actual device codes remain visible. The final adversarial Astra review also reproduced a TUI cancellation race: a delayed OAuth status response could reopen the billing-team picker after Escape. The published fix ignores status and error responses after the waiting component is disposed, preserving legitimate setup handoff. Astra reviewed the fix and reported no remaining material code findings. The 16 TUI tests passed ten consecutive runs (160 passes) under core-suite load; all 64 focused core tests, the official TUI TypeScript check, and all 35 repository checks passed.
Real browser authorization, billing-team confirmation, native Gateway generation (HTTP 200,
703), and desktop chat (391) passed on macOS using the personal test team, with no Gateway environment connection. Cancellation through the real server API released the callback listener and preserved the saved credential and active selection.The requested Internal Playground test is blocked: the app is not installed there, CLI installation returned 403, and a direct diagnostic Gateway request with the Playground selector returned 401. A Playground admin must install the app with Team Read and AI Gateway Use before fresh sign-in can verify that team. No successful Playground inference is claimed. Natural near-expiry refresh of the authorization-code grant passed: 23 consecutive native inference checks returned HTTP 200 while OpenCode silently rotated both tokens about 4m15s before expiry, preserved the connection and billing team, and advanced expiry. Desktop inference then returned
574with the replacement credentials. No browser approval or manual token/expiry changes were used. Gateway expiry enforcement has an unresolved timing observation: a direct old-token request returned HTTP 200 about five seconds after nominal expiry (response body not retained), then HTTP 401 on retry about 82 seconds after expiry. Introspection already reported the old pair inactive after rotation. Exact Gateway rejection timing and its cause remain unverified. The production client ID remains a maintainer configuration requirement.This alternative targets the same shared upstream snapshot as #5 and #6 (
vercel-oauth-base), keeping unrelated changes from the fork's staledevbranch out of the review.Provider error URLs are clickable through the existing
LinkedTextcomponent (three changed source lines), including the encoded Gateway top-up link. URL scheme colons no longer split the error title. Existing link-parser tests (3), the error-layout component check, exact-URL browser assertions against the production-compiled component, and all 35 repository checks passed.Visual