Open
Conversation
Adds a new `alchemy auth` command that authenticates via browser redirect. The CLI starts a local HTTP server on port 16424, opens the browser to authchemy, and receives the auth token via callback. New commands: - `alchemy auth` / `alchemy auth login` - browser-based login - `alchemy auth status` - show current auth state - `alchemy auth logout` - clear saved token Also updates config schema, onboarding, and error messages to recognize auth_token as a valid authentication method. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of receiving the auth token directly in the callback URL, the CLI now receives a short-lived code and exchanges it for a token via a backchannel POST to /api/cli/token. - waitForCallback() returns code + deferred response handlers - exchangeCodeForToken() handles the backchannel exchange - Browser sees success/error HTML only after exchange completes - Add withAuthRetry() helper for automatic 401 re-authentication Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix login URL to use redirectUrl (not redirect) matching authchemy frontend - Add resolveAuthToken() for reading auth token from config with expiry check - adminClientFromFlags() falls back to auth token when no access key set Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use redirectUrl (not redirect) to match authchemy frontend - Update token expiry from 24h to 90 days - Add resolveAuthToken() with expiry check - adminClientFromFlags() falls back to auth token Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- CLI sends DEFAULT_EXPIRES_IN_SECONDS (90 days) on token exchange - Use server-returned expiresAt instead of computing locally - Remove hardcoded AUTH_TOKEN_TTL_MS Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
alchemy auth now checks for an existing non-expired token first. If found, prints status and exits. Use --force to re-authenticate. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
alchemy auth logout now calls POST /api/cli/logout to invalidate the token in Redis before clearing it from the local config. Server-side revocation is best-effort — local cleanup always runs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Extract performBrowserLogin() to eliminate duplicate login flow - Simplify auth-retry to use performBrowserLogin and CLIError codes - Use resolveAuthToken() for expiry check in auth status (single source) - Remove fragile string-based 401 detection, use CLIError.code instead - Remove redundant config load in auth-retry - Add coupling comment for 90-day TTL constant Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4fb8611 to
f2676aa
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.
Summary
alchemy auth logoutnow callsPOST /api/cli/logoutto invalidate the token in Redis before clearing the local configHow it works
POST /api/cli/logoutwithAuthorization: Bearer <token>(best-effort)auth_tokenandauth_token_expires_atfrom configTest plan
alchemy auth logoutclears local config