Skip to content

feat(auth): accept a pasted redirect URL to sign in from a headless machine - #513

Open
wyattjoh wants to merge 1 commit into
mainfrom
wyattjoh/auth-paste-back-login
Open

wyattjoh wants to merge 1 commit into
mainfrom
wyattjoh/auth-paste-back-login

Conversation

@wyattjoh

@wyattjoh wyattjoh commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

What

clerk auth login can now finish on a machine without a browser. In an interactive terminal it shows a paste prompt next to the usual wait, so you can sign in on another device and paste back the URL your browser lands on.

Why

Login is an OAuth redirect to a local callback server on 127.0.0.1. Over SSH, or on any box without a GUI, you can open the printed URL on your laptop, but the final redirect then goes to the laptop's 127.0.0.1, fails to load, and the CLI waits until it times out. SSH port forwarding is the only workaround, and it's awkward because the callback port is random on every run.

How

  • The local callback server and the paste prompt race each other, and whichever delivers a code first wins. The loser is shut down: the prompt is aborted, or the server is stopped.
  • Only the full redirect URL is accepted, and it goes through the same validation as the loopback redirect. The state check refuses a URL from someone else's sign-in, so nobody can trick you into finishing their login and signing into their account (RFC 6749 §10.12). A wrong or stale URL re-prompts. A denied consent (error=) ends the login, as it does on the loopback path.
  • Nothing changes on the server side. The token exchange still uses the loopback redirect_uri, which Clerk already accepts on any port (RFC 8252 §7.3), and the code is useless without the PKCE verifier that never leaves the process (RFC 7636 §4.6). The pasted URL is never logged.
  • The paste prompt appears only in human mode with a TTY stdin. Agents, pipes, and CI keep the loopback-only wait.
  • stop() on the callback server now rejects the pending wait. Login carries on in the same process when the paste wins, and an open wait would have pinned the human-wait counter, making every later Ctrl-C exit 0. .claude/rules/interrupts.md is updated to match.
  • Device authorization (RFC 8628) was considered and not used. It is phishable by design: an attacker starts the flow and gets a victim to enter the code (RFC 8628 §5.4). It would also need the grant and a verification page configured on the CLI's OAuth app.
  • Accepted trade-off: when the loopback redirect wins, the aborted prompt's last frame stays on screen above "Completing authentication".

…achine

clerk auth login now races the loopback callback against a paste prompt in
interactive terminals. Signing in on another device leaves the browser on a
failed 127.0.0.1 redirect; pasting that URL completes the login. The pasted
URL passes the same state check as the loopback redirect, and the code is
still bound to the PKCE verifier held by the CLI.
@coderabbitai

coderabbitai Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Team
  • Run ID: 7d84da48-e029-4d74-b27c-05c2f76d5a37
📥 Commits

Reviewing files that changed from the base of the PR and between a16595f and 913a1c3.

📒 Files selected for processing (9)
  • .changeset/auth-paste-back-login.md
  • .claude/rules/interrupts.md
  • packages/cli-core/src/commands/auth/README.md
  • packages/cli-core/src/commands/auth/login.test.ts
  • packages/cli-core/src/commands/auth/login.ts
  • packages/cli-core/src/lib/auth-server.test.ts
  • packages/cli-core/src/lib/auth-server.ts
  • packages/cli-core/src/lib/prompts.ts
  • packages/cli-core/src/test/integration/lib/harness.ts
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

Included review availability: This review used your included allowance. 9 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 10 reviews per hour.


📝 Walkthrough

Walkthrough

Interactive TTY login now accepts a pasted redirect URL or the loopback callback. Pasted URLs use shared state and authorization-code validation. Login aborts the outstanding prompt and stops the authentication server when either path completes. Non-TTY and agent runs continue to use the loopback callback. The changes also update callback handling, tests, and login documentation.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: rafa-thayto

Merge Risk: ⚪ Minimal · up to 913a1

The paste-back login flow is mergeable after normal checks; the investigated validation and prompt-cancellation paths do not show a blocking issue.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: accepting a pasted redirect URL to complete authentication from a headless machine.
Description check ✅ Passed The description directly explains the pasted redirect flow, validation, eligibility rules, and callback-server behavior described by the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 10 functions across 6 files. (3 skipped: 3 …
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@changeset-bot

changeset-bot Bot commented Oct 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 913a1c3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
clerk Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@wyattjoh
wyattjoh marked this pull request as ready for review October 7, 2026 23:14
@wyattjoh

wyattjoh commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

!snapshot

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Snapshot failed

View the workflow run for details.

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.

1 participant