From 7cf6f1c7230ab74b68add40d86e9aa105e94e972 Mon Sep 17 00:00:00 2001 From: Abrar Ahmed <13979201+abrar71@users.noreply.github.com> Date: Tue, 6 Jan 2026 01:09:05 +0500 Subject: [PATCH] Use issuer URL in device auth prompt link (#7858) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary When using device-code login with a custom issuer (`--experimental_issuer`), Codex correctly uses that issuer for the auth flow β€” but the **terminal prompt still told users to open the default OpenAI device URL** (`https://auth.openai.com/codex/device`). That’s confusing and can send users to the **wrong domain** (especially for enterprise/staging issuers). This PR updates the prompt (and related URLs) to consistently use the configured issuer. 🎯 --- ## πŸ”§ What changed * πŸ”— **Device auth prompt link** now uses the configured issuer (instead of a hard-coded OpenAI URL) * 🧭 **Redirect callback URL** is derived from the same issuer for consistency * 🧼 Minor cleanup: normalize the issuer base URL once and reuse it (avoids formatting quirks like trailing `/`) --- ## πŸ§ͺ Repro + Before/After ### ▢️ Command ```bash codex login --device-auth --experimental_issuer https://auth.example.com ``` ### ❌ Before (wrong link shown) ```text 1. Open this link in your browser and sign in to your account https://auth.openai.com/codex/device ``` ### βœ… After (correct link shown) ```text 1. Open this link in your browser and sign in to your account https://auth.example.com/codex/device ``` Full example output (same as before, but with the correct URL): ```text Welcome to Codex [v0.72.0] OpenAI's command-line coding agent Follow these steps to sign in with ChatGPT using device code authorization: 1. Open this link in your browser and sign in to your account https://auth.example.com/codex/device 2. Enter this one-time code (expires in 15 minutes) BUT6-0M8K4 Device codes are a common phishing target. Never share this code. ``` --- ## βœ… Test plan * 🟦 `codex login --device-auth` (default issuer): output remains unchanged * 🟩 `codex login --device-auth --experimental_issuer https://auth.example.com`: * prompt link points to the issuer βœ… * callback URL is derived from the same issuer βœ… * no double slashes / mismatched domains βœ… Co-authored-by: Eric Traut --- codex-rs/login/src/device_code_auth.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/codex-rs/login/src/device_code_auth.rs b/codex-rs/login/src/device_code_auth.rs index d9e7d90ce..5864ff65d 100644 --- a/codex-rs/login/src/device_code_auth.rs +++ b/codex-rs/login/src/device_code_auth.rs @@ -137,26 +137,27 @@ async fn poll_for_token( } } -fn print_device_code_prompt(code: &str) { +fn print_device_code_prompt(code: &str, issuer_base_url: &str) { println!( "\nWelcome to Codex [v{ANSI_GRAY}{version}{ANSI_RESET}]\n{ANSI_GRAY}OpenAI's command-line coding agent{ANSI_RESET}\n\ \nFollow these steps to sign in with ChatGPT using device code authorization:\n\ -\n1. Open this link in your browser and sign in to your account\n {ANSI_BLUE}https://auth.openai.com/codex/device{ANSI_RESET}\n\ +\n1. Open this link in your browser and sign in to your account\n {ANSI_BLUE}{issuer_base_url}/codex/device{ANSI_RESET}\n\ \n2. Enter this one-time code {ANSI_GRAY}(expires in 15 minutes){ANSI_RESET}\n {ANSI_BLUE}{code}{ANSI_RESET}\n\ \n{ANSI_GRAY}Device codes are a common phishing target. Never share this code.{ANSI_RESET}\n", version = env!("CARGO_PKG_VERSION"), - code = code + code = code, + issuer_base_url = issuer_base_url ); } /// Full device code login flow. pub async fn run_device_code_login(opts: ServerOptions) -> std::io::Result<()> { let client = reqwest::Client::new(); - let base_url = opts.issuer.trim_end_matches('/'); - let api_base_url = format!("{}/api/accounts", opts.issuer.trim_end_matches('/')); + let issuer_base_url = opts.issuer.trim_end_matches('/'); + let api_base_url = format!("{issuer_base_url}/api/accounts"); let uc = request_user_code(&client, &api_base_url, &opts.client_id).await?; - print_device_code_prompt(&uc.user_code); + print_device_code_prompt(&uc.user_code, issuer_base_url); let code_resp = poll_for_token( &client, @@ -171,10 +172,10 @@ pub async fn run_device_code_login(opts: ServerOptions) -> std::io::Result<()> { code_verifier: code_resp.code_verifier, code_challenge: code_resp.code_challenge, }; - let redirect_uri = format!("{base_url}/deviceauth/callback"); + let redirect_uri = format!("{issuer_base_url}/deviceauth/callback"); let tokens = crate::server::exchange_code_for_tokens( - base_url, + issuer_base_url, &opts.client_id, &redirect_uri, &pkce,