Non-interactive login: a supported way to obtain the authorization URL programmatically

Status Open
Maintainer reply None cached
Activity 1 comment · opened Jul 27, 2026

Problem Statement

claude auth login is an interactive TUI. There is no --json, no --print-url, and no
machine-readable output, which makes it very hard to authenticate Claude Code in an
environment that has no terminal — a container, a pod, a CI-adjacent runner, or a
web UI that provisions dev workspaces.

I run claude remote-control in Kubernetes pods so I can pick work back up from my phone
on any of my projects. Everything else in that setup is fully declarative: repositories,
git identity, deploy keys, commit signing. Authentication is the single step that still
requires a human to open an interactive shell into the pod:

kubectl exec -it deploy/my-workspace -- claude auth login

I want to be clear about what I am not asking for: I am not looking for a way to skip
the human. OAuth requires the account owner to approve in a browser, and that is correct.
claude setup-token / CLAUDE_CODE_OAUTH_TOKEN are inference-only and rightly rejected
by Remote Control. One workspace belongs to one person, with their own subscription and
their own credentials — nothing is pooled.

What I want is to move the approval step out of the terminal and into an interface,
so the user clicks a button, approves in their browser, and pastes the code back.

Proposed Solution

A supported, non-interactive entry point to the login flow. Something like:

claude auth login --claudeai --print-url --json

returning, on stdout:

{"authorization_url": "https://claude.com/cai/oauth/authorize?...", "state": "..."}

and a matching way to submit the authorization code:

claude auth login --code "<code>"

Exit codes and a stable JSON shape would be enough. Nothing about the security model
changes: same PKCE flow, same manual redirect to platform.claude.com/oauth/code/callback,
same human approving in their own browser.

Alternative Solutions

What I do today, and why it is unsatisfying. I allocate a pseudo-terminal to the CLI
with script, scrape the authorization URL out of its output, and feed the code back
through a FIFO held open so the CLI does not see EOF. It works, and it is in production
for my own workspaces.

But it is screen-scraping a TUI, so it is not a contract. Two failures I hit while
building it, neither of which is discoverable from documentation:

  • once ANSI escapes are stripped, the two copies of the OSC 8 hyperlink end up

concatenated with no separator, so a greedy pattern captures the URL twice;

  • truncating the URL on a naive character class cuts it at the first / of the path.

Any cosmetic change to the TUI breaks this silently, and the only symptom is "no
authorization URL found". I pin the CLI version in my image because of it, and I keep the
manual command documented as a fallback. That is a lot of scaffolding to work around the
absence of one flag.

I am aware there may be internal mechanisms intended for exactly this. I have
deliberately not built on anything undocumented, and I would rather have a supported
path — happy to discuss specifics privately if that is useful.

Priority

Important - Significantly improves my workflow

Feature Category

Authentication / Remote Control

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗