1. 为什么远程 Linux 开发环境里 Codex 总是鉴权失败把 Codex App 装在本地、把代码和依赖放在远程 Linux 服务器上这个组合在团队里越来越常见。原因很直接本地机器负责图形界面和交互远程机器负责跑模型、跑依赖、跑编译。但真正配起来十个人里有八个会卡在同一个地方——本地 Codex App 明明登录正常一连上远程主机就报鉴权失败或者干脆提示找不到凭据。这个问题的本质是Codex App 通过 SSH 连接远程主机后实际执行codex app-server的是远程用户读取的是远程用户家目录下的~/.codex/auth.json。你本地那份登录凭据远程根本看不到。再加上远程服务器往往不能直连外部 API网络层和凭据层两个问题叠在一起排查起来就很绕。我试过把本地auth.json直接 scp 过去结果因为 SSH 配置里的 User 和实际登录用户不一致文件放错了家目录Codex 照样读不到。后来才理清楚远程开发场景下凭据、网络、Shell 环境这三件事必须同时对缺一个都会失败。这篇内容面向的是已经在用 Codex App、并且有远程 Linux 开发机的开发者。核心检索词就是 Codex 通过 SSH 连接远程 Linux 开发环境时的鉴权配置。我会把auth.json改到统一 Key 通道的完整配置片段、反向隧道建立步骤、以及一次真实请求的验证动作都写清楚你照着做就能跑通。需要先说明一点远程 Codex CLI 必须独立安装auth.json只是凭据文件不能代替 CLI 程序本身。这一点很多人会忽略以为复制了凭据就万事大吉。另外远程主机上的~/.codex/auth.json属于敏感凭据只能复制到你信任且自己控制的服务器。多人共享或安全性不确定的主机应该在远程独立完成登录不要图省事直接拷贝。下面按实际操作顺序展开先讲前置准备和统一 Key 通道的接入再给可复制的配置文件然后是验证请求和排错最后是长期使用的建议。2. TaoToken 前置准备与统一 Key 通道接入在动手改远程配置之前先把本地和远程要用的统一 Key 通道准备好。这一步做扎实后面远程鉴权才不会反复出问题。TaoToken 在这里扮演的角色是统一 Key 通道你不需要在每台远程机器上分别维护不同的 API 凭据而是让本地和远程都指向同一个 Base URL 和同一把 Key。这样 Codex App 在本地和远程之间切换时凭据来源是一致的不会出现「本地能跑、远程报 401」的割裂。2.1 获取 API Key 与确认 Base URL先到控制台创建一把 API Key。访问入口控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewriteAPI Keys 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite创建完成后你会拿到一串以sk-开头的 Key。把它记下来后面auth.json和远程环境变量都要用。Base URL 统一使用https://taotoken.net/api注意这里不加任何 UTM 参数API 调用地址保持干净。文档地址在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 遇到参数细节可以对照查。2.2 确认远程主机已安装 Codex CLI远程 Linux 上必须先有 Codex CLI。登录远程后执行whoami command -v codex codex --version codex login status如果command -v codex没有输出说明 CLI 没装或不在 PATH 里。先解决安装问题再谈凭据。codex login status会告诉你当前认证状态这是我们后面验证的基准。2.3 理解 auth.json 的结构Codex 的凭据文件默认在~/.codex/auth.json。它的核心字段是 API Key 和 Base URL 相关的配置。我们要做的就是让这个文件里的 Base URL 指向 TaoToken 的统一通道Key 用刚才创建的那把。一个典型的auth.json结构如下字段名以你实际版本为准这里给出可复制的模板{ OPENAI_API_KEY: sk-你的TaoToken密钥, OPENAI_BASE_URL: https://taotoken.net/api }如果你用的是较新版本可能还包含tokens或last_refresh等字段。不要手动删这些字段只改 Key 和 Base URL 即可。改之前先备份cp ~/.codex/auth.json ~/.codex/auth.json.bak2.4 本地与远程的凭据策略这里有个选择是本地和远程共用同一份auth.json还是各自独立登录。共用同一份的好处是配置简单本地改一次scp 到远程就行。前提是远程主机由你信任且仅由你控制。如果远程是多人共享的跳板机或生产环境强烈建议在远程独立登录不要拷贝本地凭据。无论哪种方式Base URL 都要指向 TaoToken 的统一通道这样本地和远程的调用行为一致排查问题时变量更少。2.5 网络层的前置判断远程服务器能不能直连外部 API决定了你要不要建反向隧道。先在远程执行curl -I https://taotoken.net/api如果返回正常的 HTTP 响应哪怕是 401说明网络可达不需要隧道。如果超时或连接被拒就需要通过反向 SSH 隧道复用本地的网络出口。下一节会给出完整的隧道配置。把这一步的判断结果记下来它直接决定你后面走哪条配置路径。3. 可复制的 auth.json 与 SSH 反向隧道配置这一节是全文的核心给出可以直接复制粘贴的配置片段。路径和字段名都按实际使用保持一致你只需要替换占位符。3.1 远程 auth.json 的完整配置在远程主机上创建并写入~/.codex/auth.json。先确保目录存在且权限正确mkdir -p ~/.codex chmod 700 ~/.codex然后写入配置。用你习惯的编辑器打开vim ~/.codex/auth.json填入以下内容把sk-你的TaoToken密钥替换成真实 Key{ OPENAI_API_KEY: sk-你的TaoToken密钥, OPENAI_BASE_URL: https://taotoken.net/api }保存后设置文件权限chmod 600 ~/.codex/auth.json权限必须是 600否则 Codex 可能拒绝读取。这一步很多人会漏导致「文件明明在就是读不到」。3.2 从本地复制 auth.json 到远程如果你选择复用本地凭据在本地机器执行以下三条命令。先确认 SSH 别名可用ssh dev-server whoami创建远程目录并设置权限ssh dev-server mkdir -p ~/.codex chmod 700 ~/.codex复制凭据文件scp $HOME/.codex/auth.json dev-server:~/.codex/auth.json最后设置远程文件权限并验证登录状态ssh dev-server chmod 600 ~/.codex/auth.json whoami codex login status预期输出类似mayu Logged in using API key关键点认证文件必须放在实际运行 Codex 的 SSH 用户家目录中。~由 SSH 登录用户解析如果 SSH 配置里的 User 写错了文件放对了位置也读不到。3.3 SSH config 的完整配置编辑本地~/.ssh/config加入两个 Host 块。一个是给 Codex App 连接用的一个是给反向隧道用的# Codex App 连接远程服务器时使用 Host dev-server HostName 192.0.2.10 User mayu Port 22 IdentityFile ~/.ssh/id_rsa IdentitiesOnly yes ServerAliveInterval 30 ServerAliveCountMax 3 # 反向代理隧道 Host dev-server-proxy HostName 192.0.2.10 User mayu Port 22 IdentityFile ~/.ssh/id_rsa IdentitiesOnly yes RemoteForward 17890 127.0.0.1:7890 ExitOnForwardFailure yes ServerAliveInterval 30 ServerAliveCountMax 3 TCPKeepAlive yes把HostName、User、IdentityFile替换成你的真实值。RemoteForward 17890 127.0.0.1:7890的含义是在远程服务器的127.0.0.1:17890上建立监听收到的流量通过 SSH 隧道转发到本地电脑的127.0.0.1:7890。注意反向隧道默认只绑定远程回环地址不要改成公网监听。这是安全底线。3.4 启动反向隧道在本地终端执行ssh -NT dev-server-proxy参数说明-N表示不执行远程命令只做端口转发-T表示不分配伪终端。这条命令会持续阻塞属于正常现象不要关闭这个窗口。如果希望重启后自动连接macOS 可以用 launchd 或 autossh 托管Windows 可以用任务计划程序。3.5 远程代理环境变量如果远程不能直连需要配置代理环境变量指向隧道端口。编辑远程~/.profilevim ~/.profile加入export HTTP_PROXYhttp://127.0.0.1:17890 export HTTPS_PROXYhttp://127.0.0.1:17890 export http_proxy$HTTP_PROXY export https_proxy$HTTPS_PROXY使配置生效source ~/.profile如果存在~/.bash_profile确保登录 Shell 会加载~/.profile[ -f $HOME/.profile ] . $HOME/.profileCodex App 通过 SSH 启动远程 app-server 时用的是远程用户的登录 Shell。所以代理环境变量和 PATH 都必须在登录 Shell 中正确加载否则 App 启动的进程读不到。3.6 包装脚本处理凭据存储方式如果直接运行codex失败但指定文件凭据存储方式后能正常工作codex -c cli_auth_credentials_storefile说明 Codex App 自动执行codex app-server时也可能读不到认证。这时创建一个包装脚本统一加配置。先确认 Codex 真实路径readlink -f $(command -v codex)创建包装脚本mkdir -p ~/bin vim ~/bin/codex写入路径替换为你的实际路径#!/bin/sh exec /usr/lib/node_modules/openai/codex/bin/codex.js \ -c cli_auth_credentials_storefile $添加执行权限chmod 755 ~/bin/codex在~/.bash_profile中加入 PATH 优先级export PATH$HOME/bin:$PATH加载并验证source ~/.bash_profile command -v codex codex --version codex login statuscommand -v codex应优先返回/home/REMOTE_USER/bin/codex。4. 验证请求与成功结果确认配置写完不代表跑通必须用真实请求验证。这一节给出从网络层到应用层的完整验证链路每一步都有明确的预期结果。4.1 验证远程代理连通性在远程主机执行env | grep -i proxy ss -lnt | grep 17890 curl -I --proxy http://127.0.0.1:17890 https://taotoken.net/api第一条确认环境变量已加载第二条确认隧道端口在监听第三条确认网络可达。如果 curl 返回类似HTTP/1.1 200 Connection established HTTP/2 401说明网络和 TLS 连接已经建立。这里的 401 不代表代理失败只是本次请求没带 API 认证信息。接下来应该检查 Codex 登录状态而不是继续改代理。4.2 验证 Codex 登录状态在远程执行codex login status预期输出类似Logged in using API key如果显示未登录回到第 3 节检查auth.json的路径和权限。4.3 用一次真实请求验证连通性这是最关键的一步。在远程执行一次非交互式请求codex exec --skip-git-repo-check 只回复连接正常预期输出连接正常如果返回了这句话说明从 SSH 登录、凭据读取、Base URL 指向、网络出口到模型调用的整条链路都通了。这是最直接的端到端验证。4.4 在 Codex App 中添加 SSH 主机打开 Codex App依次进入用户头像 - 设置 - 连接 - SSH - 添加。如果~/.ssh/config里已经配了dev-serverApp 可以自动发现该别名。也可以手动填写字段值连接名dev-server主机mayu192.0.2.10SSH 端口22身份文件~/.ssh/id_rsa4.5 打开远程项目并确认按以下步骤操作新建项目 - 远程 - 选择远程主机 - 选择项目目录 - 添加项目。连接成功后Codex 会在远程主机上读写项目文件并执行命令而对话和变更审查仍然在本地 Codex App 中完成。此时在 App 里发一条消息如果远程能正常响应说明 App 侧的 SSH 连接和远程 app-server 都工作正常。4.6 验证清单把上面的验证动作整理成一张清单每次换机器或改配置后逐项过一遍检查项命令预期远程用户whoami你的远程用户名CLI 存在command -v codex返回路径登录状态codex login statusLogged in隧道监听ss -lnt | grep 17890有监听网络可达curl -I https://taotoken.net/api有 HTTP 响应端到端codex exec --skip-git-repo-check 只回复连接正常连接正常全部通过才算真正跑通。5. 本篇常见错误排查配置过程中最容易踩的坑集中在几个固定报错上。这一节按真实报错对照排查每个都给出定位方法和修复动作。5.1 401 Unauthorized这是最常见的报错。如果 curl 返回HTTP/2 401通常代表网络和 TLS 已经建立只是请求没带认证。但如果codex exec也返回 401说明凭据没被正确读取。排查顺序cat ~/.codex/auth.json | head -5 ls -l ~/.codex/auth.json codex login status确认三件事文件存在、权限是 600、Key 和 Base URL 正确。如果 Key 里有多余空格或换行也会导致 401。5.2 local proxy failed这个报错说明 Codex 尝试走代理但连不上。检查env | grep -i proxy ss -lnt | grep 17890如果 17890 没有监听说明本地ssh -NT dev-server-proxy那个终端已经断了。重新启动隧道。如果环境变量指向的端口和隧道端口不一致也会报这个错。5.3 reading choices 相关报错如果报错信息里出现reading choices或类似的响应解析失败通常是 Base URL 指向不对请求打到了非预期端点。确认auth.json里的OPENAI_BASE_URL是https://taotoken.net/api注意结尾不要多加/v1或斜杠除非文档明确要求。路径不对会导致返回内容无法解析。5.4 OAuth 相关报错如果出现 OAuth 或 token 刷新失败说明凭据文件里的 token 字段过期或损坏。最直接的办法是重新登录codex login或者从本地重新复制一份有效的auth.json。如果远程是共享主机建议在远程独立登录不要复用本地凭据。5.5 终端能跑Codex App 找不到 codex这是登录 Shell 的 PATH 没加载导致的。用下面的命令模拟登录 Shellssh dev-server command -v codex codex --version如果没有输出检查~/.profile、~/.bash_profile或当前 Shell 对应的启动文件。Codex App 启动远程进程时用的是登录 Shell非交互式 Shell 的 PATH 可能不一样。5.6 隧道经常断开确认 SSH 配置里已加入ServerAliveInterval 30 ServerAliveCountMax 3 TCPKeepAlive yes长期运行建议用 autossh 或系统自带的任务托管机制。隧道断了之后远程的 17890 监听会消失所有走代理的请求都会失败。5.7 端口转发被拒绝如果 SSH 提示端口转发被拒绝检查远程 SSH Server 是否允许 TCP 转发。查看远程/etc/ssh/sshd_config中的AllowTcpForwarding设置。默认通常是允许的但有些加固过的服务器会关闭。5.8 安全注意事项为远程开发创建独立的普通用户避免直接用 root。SSH 私钥妥善保管并设置合理权限。不要对公网暴露 Codex App Server 的传输端口。不要在截图里泄露真实 IP、用户名、Token 或项目隐私。反向隧道默认只绑定远程回环地址不要为了方便改成公网监听。只在信任的远程主机上安装和认证 Codex。6. 长期编码场景的稳定调用建议配置跑通只是开始长期在远程开发环境里稳定使用 Codex还需要注意几件事。第一把反向隧道做成常驻服务。手动开一个终端跑ssh -NT适合调试不适合每天用。macOS 用 launchdLinux 本地用 systemd user serviceWindows 用任务计划程序都能实现开机自启和断线重连。autossh 是更省事的选择它会自动检测隧道状态并重连。第二凭据轮换要有流程。TaoToken 的 Key 如果更换本地和远程的auth.json都要同步更新。建议写一个简单的同步脚本避免手动 scp 时漏掉某台机器。脚本里记得带上权限设置scp $HOME/.codex/auth.json dev-server:~/.codex/auth.json ssh dev-server chmod 600 ~/.codex/auth.json第三远程环境变量和 PATH 的加载要验证。每次换 Shell 或改配置后用ssh dev-server command -v codex codex login status确认登录 Shell 能正确找到 CLI 和凭据。这一步能提前发现大部分「App 找不到 codex」的问题。第四如果你需要长期跑 Agent 类任务或高频编码调用可以了解 Coding Plan 的用法入口在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。它更适合持续性的编码场景和按次调用的 Key 通道互补。第五验证模型行为时可以直接用模型对话页面做对照测试入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 。当远程请求结果异常时先在对话页面用同一把 Key 发一条消息能快速判断是凭据问题还是网络问题。第六接入文档放在手边。参数、字段名、Base URL 的细节以文档为准入口在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。遇到报错先查文档比盲目改配置高效。最后说一个实际经验远程开发环境里凭据、网络、Shell 环境这三层是耦合的。任何一层出问题表现都可能是「鉴权失败」。排查时按「先网络、再凭据、后 Shell」的顺序逐层确认比一上来就改auth.json有效得多。把第 4 节的验证清单存成脚本每次环境变动后跑一遍能省下大量来回试错的时间。