OpenAI Codex CLI 认证、模型额度与 Remote Control 故障解决报告
OpenAI Codex CLI 认证、模型额度与 Remote Control 排障报告
本文为公开脱敏版。文中的主机名、账号、会话 ID、设备码、配对码、具体服务器路径及精确时间均使用通用变量或占位符表示。
一、环境与最终状态
测试环境:
- 远程 Linux 服务器
- OpenAI Codex CLI standalone 安装
- 使用 ChatGPT 账号通过设备码登录
- 使用 Remote Control 连接远程设备
本文统一使用以下路径变量:
export CODEX_HOME="$HOME/.codex"
export CODEX_CLEAN_HOME="$HOME/.codex-clean-test"
最终状态:
Codex 主认证:正常
access token:正常
refresh token:正常
Codex Spark 模型:可正常调用
默认高能力模型:因额度耗尽暂时不可用
codex_apps:已临时关闭
standalone 安装:正常
Remote Control:启动成功
最终推荐配置:
model = "gpt-5.3-codex-spark"
cli_auth_credentials_store = "file"
[features]
apps = false
如需信任特定项目目录,可以另外添加:
[projects."/path/to/project"]
trust_level = "trusted"
二、问题总览
本次连续遇到了四类不同问题:
codex_apps启动时返回HTTP 401 token_revoked- Codex 主登录的 refresh token 被撤销
- 默认模型额度耗尽
- Remote Control 找不到 standalone Codex 安装
这些问题互相独立,不能只通过重复登录一次性解决。
三、问题一:codex_apps 返回 HTTP 401
3.1 错误表现
Codex 启动时出现:
MCP client for `codex_apps` failed to start
HTTP 401
Encountered invalidated oauth token for user
code: token_revoked
同时可能出现:
MCP startup incomplete (failed: codex_apps)
3.2 错误含义
失败的是 Codex 内置的 Apps/Connectors 集成层,而不一定是主模型认证。
codex_apps 主要负责接入外部应用或托管连接器,例如:
- Google Drive
- Slack
- GitHub 连接器
- 其他 ChatGPT Apps
下面的命令显示没有自定义 MCP:
codex mcp list
可能输出:
No MCP servers configured yet.
这与 codex_apps 报错并不矛盾,因为 codex_apps 是内置连接器,不一定出现在手动配置的 MCP 列表中。
四、为什么删除 auth.json 后仍可能报错
初步尝试通常包括:
codex logout
codex login status
rm -f "$HOME/.codex/auth.json"
rm -f "$HOME/.codex/oauth.json"
codex login
但删除文件后,codex_apps 仍可能继续返回:
HTTP 401
token_revoked
原因可能包括:
- 实际使用的
CODEX_HOME不是$HOME/.codex - 凭证存储在系统 keyring 中
- 主认证与 Apps OAuth 是两套认证
- 其他 Codex 进程仍持有旧 token
- 另一台设备或 IDE 扩展触发了 token 轮换
- 服务端已经撤销旧 refresh token
- 工作区切换导致旧授权失效
因此,删除默认目录中的 JSON 文件,不一定代表所有认证状态都已清除。
五、创建隔离的干净认证环境
为了排除旧缓存和系统 keyring,可以创建一个全新的 CODEX_HOME。
codex logout 2>/dev/null || true
unset OPENAI_API_KEY
unset CODEX_ACCESS_TOKEN
unset CODEX_API_KEY
export CODEX_CLEAN_HOME="$HOME/.codex-clean-test"
export CODEX_HOME="$CODEX_CLEAN_HOME"
rm -rf "$CODEX_HOME"
install -d -m 700 "$CODEX_HOME"
printf '%s\n' \
'cli_auth_credentials_store = "file"' \
> "$CODEX_HOME/config.toml"
chmod 600 "$CODEX_HOME/config.toml"
codex login --device-auth
设备码登录时:
- 打开终端显示的官方登录页面
- 输入一次性设备码
- 登录正确的 ChatGPT 账号
- 选择正确的个人或团队工作区
- 登录完成前,不要在其他终端执行
codex logout
登录成功后会显示:
Successfully logged in
六、为什么“刚登录能用”,随后又提示 refresh token revoked
可能出现以下现象:
- 设备码登录成功
- Codex 界面可以启动
- 模型菜单可以切换
- 真正发送模型请求时出现:
Your access token could not be refreshed because your refresh token was revoked.
这两件事并不矛盾。
Codex 登录凭证通常包括:
access_token
refresh_token
id_token
刚登录后,新的 access_token 可能暂时有效,因此 Codex 可以:
- 启动界面
- 读取配置
- 显示模型列表
- 执行部分本地操作
当 access token 需要刷新时,Codex 会使用 refresh_token。
如果 refresh token 已被撤销或轮换,就会在这时暴露错误。
因此:
codex login status
只能说明本地存在登录信息,不代表完整认证链路一定正常。
必须通过真实模型请求验证。
七、重新生成主认证
首先关闭可能持有旧凭证的进程:
pkill -TERM -x codex 2>/dev/null || true
pkill -TERM -f 'codex.*app-server' 2>/dev/null || true
sleep 2
pgrep -af codex || true
固定认证目录并清除环境变量:
export CODEX_HOME="$HOME/.codex-clean-test"
unset OPENAI_API_KEY
unset CODEX_ACCESS_TOKEN
unset CODEX_API_KEY
备份旧认证:
mkdir -p "$CODEX_HOME/auth-backup"
if [ -f "$CODEX_HOME/auth.json" ]; then
cp -a "$CODEX_HOME/auth.json" \
"$CODEX_HOME/auth-backup/auth.json.$(date +%Y%m%d-%H%M%S).bak"
fi
删除失效凭证:
rm -f "$CODEX_HOME/auth.json"
rm -f "$CODEX_HOME/oauth.json"
重新登录:
codex login --device-auth
八、关闭异常的 codex_apps
如果主模型功能正常,但 codex_apps 仍然持续报 token_revoked,可以临时关闭 Apps 集成。
写入配置:
printf '%s\n' \
'cli_auth_credentials_store = "file"' \
'' \
'[features]' \
'apps = false' \
> "$CODEX_HOME/config.toml"
chmod 600 "$CODEX_HOME/config.toml"
cat "$CODEX_HOME/config.toml"
正确内容:
cli_auth_credentials_store = "file"
[features]
apps = false
关闭 apps 不会影响:
- 本地代码读取
- 修改文件
- Shell 命令
- Git
- 编译和测试
/review- 普通模型调用
- Remote Control
关闭后暂时不能使用:
- ChatGPT Apps
- 外部 Connectors
- 依赖
codex_apps的托管 MCP 工具
九、安全检查认证文件
检查登录状态:
codex login status
ls -l "$CODEX_HOME/auth.json"
正常应看到:
Logged in using ChatGPT
并且 auth.json 权限应类似:
-rw-------
可以使用下面的 Python 脚本,只检查 token 字段是否存在,不显示真实内容:
python3 - <<'PY'
import json
import os
codex_home = os.environ.get(
"CODEX_HOME",
os.path.expanduser("~/.codex"),
)
path = os.path.join(codex_home, "auth.json")
with open(path, "r", encoding="utf-8") as f:
auth = json.load(f)
tokens = auth.get("tokens") or {}
print("auth_file:", path)
print("auth_mode:", auth.get("auth_mode"))
print("has_access_token:", bool(tokens.get("access_token")))
print("has_refresh_token:", bool(tokens.get("refresh_token")))
print("has_id_token:", bool(tokens.get("id_token")))
print("last_refresh_exists:", bool(auth.get("last_refresh")))
PY
正常结果:
auth_mode: chatgpt
has_access_token: True
has_refresh_token: True
has_id_token: True
last_refresh_exists: True
不要公开执行或粘贴:
cat "$CODEX_HOME/auth.json"
也不要公开:
- access token
- refresh token
- id token
- Cookie
- Authorization header
- 完整
auth.json
十、使用真实模型请求验证认证
不要只依赖:
codex login status
应当执行真实请求:
env -u OPENAI_API_KEY \
-u CODEX_ACCESS_TOKEN \
-u CODEX_API_KEY \
CODEX_HOME="$CODEX_HOME" \
codex exec \
--skip-git-repo-check \
--ephemeral \
'Reply with exactly OK and nothing else.'
可能出现三类结果。
10.1 返回 OK
说明以下链路正常:
auth.json
→ access token
→ Codex 服务
→ 模型响应
10.2 返回 refresh token was revoked
说明主认证仍然失效,需要重新停止所有 Codex 进程并执行设备码登录。
10.3 返回 You've hit your usage limit
说明认证已经成功,只是当前模型额度耗尽。
额度错误不是认证错误,不需要继续反复退出登录。
十一、默认模型额度耗尽后的处理
默认模型可能返回:
You've hit your usage limit.
Try again at <RESET_TIME>.
这说明:
账号认证正常
当前模型额度耗尽
可以切换到仍有可用额度的 Spark 模型:
env -u OPENAI_API_KEY \
-u CODEX_ACCESS_TOKEN \
-u CODEX_API_KEY \
CODEX_HOME="$CODEX_HOME" \
codex exec \
-m gpt-5.3-codex-spark \
--skip-git-repo-check \
--ephemeral \
'Reply with exactly OK and nothing else.'
返回:
OK
即表示 Spark 可用。
交互式启动:
codex -m gpt-5.3-codex-spark
设为默认模型:
model = "gpt-5.3-codex-spark"
完整配置示例:
model = "gpt-5.3-codex-spark"
cli_auth_credentials_store = "file"
[features]
apps = false
十二、不要移动整个 $HOME/.codex
曾经为了隔离旧状态,移动了整个默认目录:
mv "$HOME/.codex" "$HOME/.codex-broken-backup"
随后执行:
codex
可能出现:
No such file or directory
原因是 standalone 安装方式下,$HOME/.codex 不只是认证目录,还可能包含:
$HOME/.codex/packages/standalone/current/codex
$HOME/.local/bin/codex 可能依赖这个实际程序路径。
所以移动整个 $HOME/.codex,可能同时移走:
- Codex standalone 程序
- app-server
- Remote Control 所需组件
- 版本元数据
- 安装器管理文件
恢复方法:
mv "$HOME/.codex-broken-backup" "$HOME/.codex"
hash -r
以后需要重置认证时,只处理:
$CODEX_HOME/auth.json
$CODEX_HOME/oauth.json
不要直接删除或移动整个 $HOME/.codex。
十三、Remote Control 找不到 standalone 安装
在使用隔离目录时:
export CODEX_HOME="$HOME/.codex-clean-test"
执行:
codex remote-control start
可能报错:
managed standalone Codex install not found at
$CODEX_HOME/packages/standalone/current/codex
原因是干净目录中只有:
auth.json
config.toml
但 Remote Control 要求当前 CODEX_HOME 中同时存在:
packages/standalone/current/codex
普通 Codex 命令可以通过 PATH 中的入口运行,但 Remote Control daemon 要求使用安装器管理的固定 standalone 路径。
十四、将有效认证迁移回正式目录
首先确认正式目录中存在 standalone:
export CODEX_HOME="$HOME/.codex"
ls -l "$CODEX_HOME/packages/standalone/current/codex"
停止相关进程:
pkill -TERM -x codex 2>/dev/null || true
pkill -TERM -f 'codex.*app-server' 2>/dev/null || true
sleep 2
备份正式目录中的旧认证:
mkdir -p "$HOME/.codex/auth-backup"
if [ -f "$HOME/.codex/auth.json" ]; then
mv "$HOME/.codex/auth.json" \
"$HOME/.codex/auth-backup/auth.json.old.$(date +%Y%m%d-%H%M%S)"
fi
if [ -f "$HOME/.codex/config.toml" ]; then
cp -a "$HOME/.codex/config.toml" \
"$HOME/.codex/auth-backup/config.toml.old.$(date +%Y%m%d-%H%M%S)"
fi
复制已验证成功的认证和配置:
install -m 600 \
"$HOME/.codex-clean-test/auth.json" \
"$HOME/.codex/auth.json"
install -m 600 \
"$HOME/.codex-clean-test/config.toml" \
"$HOME/.codex/config.toml"
统一使用正式目录:
export CODEX_HOME="$HOME/.codex"
unset OPENAI_API_KEY
unset CODEX_ACCESS_TOKEN
unset CODEX_API_KEY
hash -r
验证:
echo "$CODEX_HOME"
codex login status
ls -l "$CODEX_HOME/packages/standalone/current/codex"
十五、迁移后验证 Spark
env -u OPENAI_API_KEY \
-u CODEX_ACCESS_TOKEN \
-u CODEX_API_KEY \
CODEX_HOME="$HOME/.codex" \
codex exec \
-m gpt-5.3-codex-spark \
--skip-git-repo-check \
--ephemeral \
'Reply with exactly OK and nothing else.'
返回:
OK
说明有效认证已经成功迁移到正式 CODEX_HOME。
十六、启动 Remote Control
统一目录后执行:
export CODEX_HOME="$HOME/.codex"
codex remote-control stop 2>/dev/null || true
codex remote-control start
codex remote-control pair
启动成功时会出现类似:
Starting app-server daemon with remote control enabled...
This machine is available for remote control as <SERVER_HOSTNAME>.
Daemon used app-server:
path: <CODEX_HOME>/packages/standalone/current/codex
version: <CODEX_VERSION>
Pairing code: <PAIRING_CODE>
不要公开真实配对码。
如果配对码曾被发到聊天、论坛、截图或日志中,应重新生成:
codex remote-control pair
只在自己的受信任设备中输入新配对码。
十七、永久固定 CODEX_HOME
将正式目录写入 Shell 配置:
grep -qxF 'export CODEX_HOME="$HOME/.codex"' "$HOME/.bashrc" ||
echo 'export CODEX_HOME="$HOME/.codex"' >> "$HOME/.bashrc"
source "$HOME/.bashrc"
验证:
echo "$CODEX_HOME"
应输出:
<用户主目录>/.codex
检查最终配置:
cat "$CODEX_HOME/config.toml"
推荐配置:
model = "gpt-5.3-codex-spark"
cli_auth_credentials_store = "file"
[features]
apps = false
十八、可直接复用的标准恢复流程
18.1 固定正式目录
export CODEX_HOME="$HOME/.codex"
18.2 排除环境变量干扰
unset OPENAI_API_KEY
unset CODEX_ACCESS_TOKEN
unset CODEX_API_KEY
18.3 停止旧进程
pkill -TERM -x codex 2>/dev/null || true
pkill -TERM -f 'codex.*app-server' 2>/dev/null || true
sleep 2
18.4 备份认证
mkdir -p "$CODEX_HOME/auth-backup"
if [ -f "$CODEX_HOME/auth.json" ]; then
cp -a "$CODEX_HOME/auth.json" \
"$CODEX_HOME/auth-backup/auth.json.$(date +%Y%m%d-%H%M%S).bak"
fi
18.5 删除失效认证
rm -f "$CODEX_HOME/auth.json"
rm -f "$CODEX_HOME/oauth.json"
18.6 写入最小配置
printf '%s\n' \
'model = "gpt-5.3-codex-spark"' \
'cli_auth_credentials_store = "file"' \
'' \
'[features]' \
'apps = false' \
> "$CODEX_HOME/config.toml"
chmod 600 "$CODEX_HOME/config.toml"
18.7 重新登录
codex login --device-auth
18.8 验证登录结构
codex login status
ls -l "$CODEX_HOME/auth.json"
18.9 进行真实模型测试
env -u OPENAI_API_KEY \
-u CODEX_ACCESS_TOKEN \
-u CODEX_API_KEY \
CODEX_HOME="$CODEX_HOME" \
codex exec \
-m gpt-5.3-codex-spark \
--skip-git-repo-check \
--ephemeral \
'Reply with exactly OK and nothing else.'
18.10 启动 Remote Control
codex remote-control stop 2>/dev/null || true
codex remote-control start
codex remote-control pair
十九、错误信息快速判断表
codex_apps token_revoked
MCP client for codex_apps failed
HTTP 401
token_revoked
含义:
Apps/Connectors OAuth 失效
临时处理:
[features]
apps = false
refresh token was revoked
Your access token could not be refreshed because your refresh token was revoked.
含义:
Codex 主认证失效
处理:
停止所有 Codex 进程
删除 auth.json
重新执行设备码登录
使用 codex exec 真实验证
You've hit your usage limit
含义:
认证成功,但当前模型额度耗尽
处理:
codex -m gpt-5.3-codex-spark
不要因此反复退出登录。
No such file or directory
如果 Codex 命令入口突然失效,并且此前移动过 $HOME/.codex:
standalone 安装目录被移动
恢复:
mv "$HOME/.codex-broken-backup" "$HOME/.codex"
hash -r
managed standalone Codex install not found
含义:
当前 CODEX_HOME 中没有 standalone 安装
处理:
统一使用包含 packages/standalone 的正式 CODEX_HOME
或在当前 CODEX_HOME 下重新运行 Codex installer
Remote control is not enabled for this team
含义:
当前团队工作区可能未开放 Remote Control
检查:
- 手机与服务器是否使用同一账号
- 是否选择了同一个工作区
- 个人工作区是否可用
- 团队管理员是否启用了相关权限
二十、公开分享时必须删除的信息
发布日志或教程前,必须删除或替换:
真实主机名
公网 IP
SSH 地址
用户名
会话 ID
codex resume ID
设备登录码
Remote Control 配对码
access token
refresh token
id token
Cookie
Authorization header
完整 auth.json
团队名称
个人邮箱
精确额度恢复时间
推荐替换格式:
<SERVER_HOSTNAME>
<SERVER_IP>
<USERNAME>
<SESSION_ID>
<DEVICE_CODE>
<PAIRING_CODE>
<RESET_TIME>
<WORKSPACE_NAME>
可以公开:
错误类型
通用目录结构
脱敏后的命令
软件版本
配置字段
不包含 token 的布尔检查结果
二十一、核心经验
codex_apps错误与 Codex 主模型认证不是同一层问题。codex login status不能替代真实模型请求验证。usage limit表示认证成功,不是 token 失效。- standalone 安装下,不要移动整个
$HOME/.codex。 - Remote Control 要求当前
CODEX_HOME中存在 standalone 程序。 - 配置、认证和 Remote Control 最好统一使用同一个正式
CODEX_HOME。 - 出现认证问题时,只重置认证文件,不要删除整个安装目录。
- 所有设备码、配对码和 token 都不应出现在公开日志中。
更多推荐



所有评论(0)