
如果你在一个需要走代理的企业网络里用 OpenCode 接 Antigravity Auth你大概率会经历这么一幕登录命令敲下去浏览器弹出授权页你点了“同意”然后终端里彻底卡住没有任何回调提示或者干脆跳出一段error from provider (console)末尾挂着一句opencodes free tier can only be used from within opencode。这篇文章就是把这类问题串起来讲清楚OpenCode 的 Antigravity Auth 走的是标准 OAuth 认证代理一介入链路里几个不起眼的环节就会轮番出问题。我会从认证链路本身讲起再给出一套可以照着抄的排查和配置步骤覆盖本地开发机、WSL、远程服务器和 CI 环境。无论你是第一次跑opencode auth login还是已经在生产环境里被回调地址折腾过这篇文章都应该能帮你省下半天时间。1. 代理环境下做 OAuth 认证为什么这么容易翻车1.1 OpenCode Antigravity Auth 的认证链路长什么样OpenCode 是终端里的 AI 编码代理它能在你的代码仓库里读文件、改代码、跑命令。要接入模型服务OpenCode 支持多种认证方式其中 Antigravity Auth 走的是典型的 OAuth 2.0 Authorization Code PKCE 流程。这个流程的设计初衷是为了不让用户把密码交给第三方 CLI 工具而是由用户自己在浏览器里完成身份确认。整个链路可以拆成六步每一环都有可能出现问题OpenCode 启动一个本地 HTTP 回调服务监听127.0.0.1上的某个随机端口。OpenCode 打开系统浏览器跳转到 Antigravity 的授权页面URL 参数里带着client_id、redirect_uri、code_challenge等。你在浏览器里登录 Antigravity 账号点击“授权”。浏览器把授权服务器返回的authorization code发送到第 1 步里的redirect_uri也就是本地回调服务。本地回调服务收到 code 之后用 code PKCE verifier 向 Antigravity 的 token 端点换取 access token 和 refresh token。OpenCode 把 token 落盘保存后续请求模型服务都带上这个 token。这套流程在普通网络环境里很顺滑但一旦你被夹在企业代理后面第 2 步、第 4 步、第 5 步都会变成雷区。1.2 代理介入后三个最容易出问题的环节先说结论代理环境下的 OAuth 故障九成以上集中在这三个环节。第一个是浏览器访问授权页。现在很多办公网络要求所有 HTTPS 流量都走统一出口代理浏览器一般会自动使用系统代理设置所以第 2 步通常能过。但如果你是在无头服务器上跑 OpenCode连浏览器都没有这一步直接就会卡死。第二个是本地回调被代理拦截。OAuth 的redirect_uri一般是http://127.0.0.1:随机端口/callback。问题在于如果你在环境变量里设置了HTTP_PROXY和HTTPS_PROXY很多命令行工具和运行时会把所有请求都交给代理包括发往127.0.0.1的回调请求。代理服务器收到一个http://127.0.0.1:45678/callback的请求大概率是把它转发到外网茫茫互联网里去找目标结果自然是找不到。本地回调服务等不到请求终端就一直卡在 Waiting for redirect...。这个问题的根因很简单缺少NO_PROXY或者NO_PROXY里没写localhost和127.0.0.1。第三个是服务端到 token 端点的请求被代理的 TLS 证书拦下。第 5 步里 OpenCode 作为客户端要向https://auth.antigravity.com之类的地址发请求。如果企业代理做了 SSL 解密它会给所有经它中转的 HTTPS 连接换上一张企业自签 CA 证书。OpenCode 的运行时如果不信任这张 CA就会报证书链错误比如self-signed certificate in certificate chain或UNABLE_TO_VERIFY_LEAF_SIGNATUREtoken 换不来登录同样失败。搞清楚了这三个环节后面所有的排查其实都是在回答同一个问题当前这个请求到底应该走代理还是应该绕过代理2. 动手之前三分钟的“环境自检”别急着敲登录命令先花三分钟把环境摸清楚。我在帮同事处理这类问题时发现大部分人失败是因为环境变量本身是乱的而不是 OpenCode 配置有问题。2.1 确认安装方式与命令行可达先确认 OpenCode 的安装方式和版本。不同版本的 CLI 命令可能有细微差异但一般都会有opencode auth这个子命令组。先跑一下opencode auth --help如果提示找不到命令先解决 PATH 问题。Windows 上常见的报错是cmd 使用 opencode 命令无效多半是 npm 的全局 bin 目录不在 PATH 里还有一种是node_modules\opencode\cli\bin\opencode.exe 与你运行的 Windows 版本不兼容这种情况通常是 Node 版本太旧或者安装包下载不完整升级到当前 LTS 版本的 Node 再重装一次基本能解决。版本确认完了再看安装来源。用 npm 装的、用官方安装脚本装的、还是直接下载二进制包的这决定了后面排查代理时要改哪些配置。npm 装的需要额外注意 npm 自己的代理设置npm config get proxy npm config get https-proxy npm config get registry如果这些是空的而你又确定公司网络需要代理才能访问外网那么 npm install 这一步就会很慢或直接失败OpenCode 都装不上后面认证更是无从谈起。用官方安装脚本的话记得先看脚本是否依赖 curl 或 wget这两个工具都会读环境变量里的代理配置。2.2 把代理环境变量梳理清楚接下来看当前 shell 里到底有哪些代理相关的变量。直接用命令打印env | grep -i proxy你会看到四种常见变量HTTP_PROXY、HTTPS_PROXY、ALL_PROXY、NO_PROXY。这里有两个容易踩的坑第一个坑是大小写。Linux 下的很多工具只认小写形式但也有不少 Node.js 库和 Java 程序对大小写不敏感甚至只认大写。为了避免工具链之间互相打架我习惯在~/.bashrc或~/.zshrc里同时导出大小写两套export http_proxyhttp://proxy.corp.example:8080 export https_proxyhttp://proxy.corp.example:8080 export HTTP_PROXY$http_proxy export HTTPS_PROXY$https_proxy第二个坑是NO_PROXY。这个变量决定了哪些地址必须绕过代理直连。OAuth 本地回调能不能成功全靠它export no_proxylocalhost,127.0.0.1,*.local,.corp.example export NO_PROXY$no_proxy注意NO_PROXY里写不写*.corp.example取决于你公司内网域名长什么样。如果内网服务域名五花八门就先别写太多通配保持最小集合localhost,127.0.0.1最安全。因为如果NO_PROXY配得太宽某些必须走代理才能访问的外部地址会被错误地绕过代理结果是连接超时。2.3 查看已有认证状态与配置文件接下来看看 OpenCode 现在认不认你已经登录过。一般 CLI 都有类似的检查命令opencode auth list opencode auth status如果显示没有活动的认证会话那就需要登录。还需要确认配置文件的位置。OpenCode 配置通常在~/.config/opencode/opencode.jsonLinux/macOS或 Windows 用户目录下里面记录了 provider 和 auth 块。如果你之前手动改过配置先备份一下然后看一眼是不是有残留的 auth 条目导致登录时走到了错误的 provider。我见过一种典型情况用户之前在 OpenCode 里配置了其他 provider再跑opencode auth login时交互式菜单里选了 Antigravity但配置文件里旧 provider 的apiKey还在LLM 请求优先走了旧配置看起来像 Antigravity 登录没生效。所以在自检阶段梳理配置文件能避免后面产生“明明登录成功但模型不可用”的错觉。3. 完整走一遍代理环境下的 Antigravity Auth 登录自检完毕开始正式登录。这里我不假设你已经有一份完美的配置而是按“最可能出问题”的顺序一步步说清楚每个阶段应该看到什么、如果看不到该怎么处理。3.1 启动登录先搞清楚它监听哪个回调端口启动登录命令opencode auth login交互式菜单里选择 Antigravity Auth。这时候 OpenCode 会做两件事拉起一个本地 HTTP 服务然后尝试打开浏览器。如果是在无图形界面的服务器上浏览器那一步会失败但日志里一般会输出一个授权 URL你可以手动复制到本地浏览器里打开。重点来了在这一步就要注意到回调端口。OpenCode 通常是随机选一个高端口号比如 34251、51234也可能固定 8899。日志一般会显示类似Listening on http://127.0.0.1:34251/callback的信息。记下这个地址后面排查要用。如果你用的是 Windows有时候系统会自动弹窗问“是否允许此应用在防火墙中通信”这个一定要允许否则本地回调服务根本收不到连接。3.2 让本地回环流量绕过代理NO_PROXY 的关键作用前面说过OpenCode 起了一个本地回调服务。浏览器在授权完成后会重定向到http://127.0.0.1:端口/callback。如果 OpenCode 自身的进程也设置了HTTPS_PROXYNode.js 的 fetch 或底层 HTTP 客户端在发起回调监听时一般不受影响但有些工具在回调之后还要向本地地址回发请求这时候就可能被代理环境变量干扰。最稳妥的做法是在跑登录命令前明确告诉运行时什么样的地址不要走代理export NO_PROXYlocalhost,127.0.0.1,::1 export no_proxy$NO_PROXY很多 OpenCode 内置的依赖比如 undici对NO_PROXY的解析比较严格它支持127.0.0.1也支持localhost但如果你只写了localhost请求目标是127.0.0.1时仍然可能被代理接管。所以我建议把两个都写上IPv6 的::1也写上虽然用得少但能避免偶发问题。还有个细节如果你在浏览器里用的是系统代理Windows 的“Internet 选项 - 连接 - 局域网设置”里的“为本地地址绕过代理服务器”勾选要打开。否则浏览器把http://127.0.0.1:34251/callback也交给了系统代理结果一样是回调失败。3.3 处理代理的 TLS 证书拦截如果授权页能打开浏览器里也点了同意但 OpenCode 终端紧接着报 TLS 错误那基本就是代理做了 SSL 解密。怎么判断看报错信息里有没有certificate、SSL、SELF_SIGNED一类字样。处理方式不是关掉证书校验而是把企业代理的根 CA 证书加进 Node.js 的信任列表。Node.js 有一个专门的环境变量NODE_EXTRA_CA_CERTS指向一个包含额外根证书的 PEM 文件export NODE_EXTRA_CA_CERTS/etc/ssl/certs/corp-ca.pem注意这个变量只对 Node.js 进程生效所以必须保证它在你启动 OpenCode 的同一个 shell 环境里。如果 OpenCode 是从桌面图标或 IDE 插件里启动的你可能需要在系统环境变量里也加上这一项。更通用一点的做法是把企业 CA 装进系统证书库。Linux 上一般是把 CA 文件放到/usr/local/share/ca-certificates/然后运行update-ca-certificates。这样不仅 OpenCodecurl、git、npm 也都能信任这张证书。我不建议设NODE_TLS_REJECT_UNAUTHORIZED0。虽然它确实能绕过证书错误让登录跑通但相当于关掉了整个 Node 进程的 TLS 校验后续所有 HTTPS 请求都可能被中间人攻击。用来临时定位问题可以作为长期方案就算了。3.4 登录成功后的 Token 存储与验证登录成功时OpenCode 一般会打印类似Authentication successful的信息。Token 会写入配置目录下的某个文件里通常是~/.config/opencode/auth.json之类的文件。你可以看一下这个文件的权限ls -l ~/.config/opencode/auth.json chmod 600 ~/.config/opencode/auth.json权限一定不能是 644因为里面存的是 access token 和 refresh token任何同机用户都能读走就麻烦了。验证登录是否真正生效最直接的办法是问 OpenCode 当前的认证信息opencode auth list如果列表里出现 Antigravity 且状态不是 expired基本就算成了。接下来随便跑一个简单的模型请求能正常返回就说明从认证到模型调用的完整链路是通的。4. 高频报错排查从报错信息反推链路断点这一节我把平时遇到频率最高的几个报错整理成了一张实战排查表。每个报错看起来吓人但只要你知道它对应的是链路里的哪一环处理起来其实很快。报错现象链路断点直接原因处理方式终端一直卡在 waiting没有任何报错第 4 步本地回调NO_PROXY缺失或系统代理接管了 127.0.0.1补全NO_PROXY关闭系统代理的“本地地址走代理”error from provider (console): opencodes free tier can only be used from within opencode认证后调用阶段把登录会话 token 当 API Key 外带使用在 OpenCode 内使用独立 API Key 去控制台创建WSL 报检测到 localhost 代理配置但未镜像到 WSL环境变量传递WSL2 NAT 模式下不会同步宿主机的 localhost 代理在 WSL 里显式设置代理地址为宿主机 IP或用 mirrored 模式self-signed certificate in certificate chain第 5 步 token 换取代理 SSL 解密后用了企业自签证书把企业 CA 加入NODE_EXTRA_CA_CERTS或系统证书库点完授权之后浏览器显示 ERR_CONNECTION_REFUSED第 4 步本地回调回调端口被防火墙拦或 OpenCode 进程已退出放行端口确认进程还活着登录成功但马上 401 Unauthorized第 6 步请求模型refresh token 过期或系统时钟偏差重新登录并同步 NTP 时间4.1 error from provider: free tier can only be used from within opencode这个报错我单独拿出来说因为它的误导性最强。它看起来像代理问题、像网络问题但实际上和代理一点关系都没有。错误原文是opencodes free tier can only be used from within opencode。意思很明确通过 Antigravity Auth 登录到 OpenCode 后获得的免费额度 Token只能在 OpenCode 客户端内部使用不能复制出来单独调用模型 API。很多人包括我第一次遇到时会下意识地去检查代理配置折腾半天才发现是自己把登录后打印出来的 token 粘到 curl 脚本里测接口了。正确理解是OpenCode 的免费额度绑定的是 OpenCode 这个客户端环境。如果你想在脚本、curl、或者其他程序里直接调用 Antigravity 的模型接口应该去 Antigravity 控制台创建一个独立的 API Key而不是拿 OpenCode 的登录会话 Token 来用。这两个东西的权限边界完全不同登录 Token 相当于“我是合法登录用户”API Key 才相当于“我可独立调用服务”。4.2 WSL 下 localhost 代理未镜像到 Linux 子系统Windows WSL2 的环境特别容易出这个问题。报错信息一般长这样wsl: 检测到 localhost 代理配置,但未镜像到 wsl。nat 模式下的 wsl 不支持 localhost 代理转发。这句报错的本质是WSL2 默认使用 NAT 网络模式宿主机 Windows 上的代理设置比如某些代理工具设置的 localhost 监听不会自动出现在 WSL 的 Linux 网络栈里。你在 Windows 上跑opencode auth login时浏览器回调能成功但同样命令在 WSL 里跑回调请求就找不到本地的代理端口或者反过来WSL 内访问宿主机服务时地址完全不对。有两个解决思路。第一个是在 WSL 里显式设置代理地址指向 Windows 宿主机的局域网 IP而不是 localhost。先看宿主机的 IP# 在 WSL 里执行 ip route show | grep default默认网关 IP 一般就是宿主机在 WSL 网络中的地址。然后设置export HTTPS_PROXYhttp://宿主机IP:代理端口 export NO_PROXYlocalhost,127.0.0.1第二个是开启 WSL 的 mirrored 网络模式。Windows 11 较新的版本支持在.wslconfig里配置[wsl2] networkingModemirrored然后重启 WSL。这个模式会把 localhost 变成互通地址宿主机和 WSL 之间的代理转发更自然。但要注意mirrored 模式不是所有环境都稳定如果你公司网络环境和 Docker Desktop 有冲突可能需要权衡。4.3 回调地址被代理“吃掉”终端卡在 waiting for callback这是最经典的问题。我在第 1 节讲过原理这里补充一个快速定位方法。当 OpenCode 卡在等待回调时你先不要关掉它开另一个终端查看 127.0.0.1 上是否有进程在监听lsof -i :34251其中 34251 换成 OpenCode 日志里显示的那个端口。如果监听进程存在说明 OpenCode 本身没问题问题出在请求根本没到达这个端口。这时候看一下浏览器授权完成后的地址栏如果浏览器跳转到了一个看起来像外网的错误页那就是系统代理把127.0.0.1劫持走了。处理方式就两招一是在代理环境变量里补NO_PROXYlocalhost,127.0.0.1二是把 Windows 的“局域网设置 - 为本地地址绕过代理服务器”勾上。如果正在用某些带“全局模式”的本地代理工具把它切回规则模式别让它接管回环流量。4.4 代理链路里的 TLS 证书链错误这一类报错在日志里通常很显眼因为 Node.js 会把整条证书链错误打出来。很多人的第一反应是export NODE_TLS_REJECT_UNAUTHORIZED0跑通了就再也不管。我强烈建议不要这样。正确做法前面提过找到企业的根 CA 证书导出成 PEM 格式然后配置NODE_EXTRA_CA_CERTS。如果你用的是 Charles 或 Fiddler 之类的调试工具做 HTTPS 抓包它们的根证书同样需要加进信任列表。如果你只想用一次也可以在命令行里临时指定证书参数但更好的做法是把它固化到环境变量里避免下次登录再次踩坑。如果你不确定该信任哪张证书可以在浏览器里打开授权页点地址栏的小锁图标查看证书链把最顶层的根证书导出来。这通常就是需要加入信任的那张。4.5 用抓包工具确认流量走向当所有配置看起来都对、但登录就是失败时抓包是最好的最终裁决手段。Charles、Fiddler 这类工具本质也是一个本地代理你把 OpenCode 的流量指到它们的监听端口就能看清回调请求到底去了哪里。具体的做法是把HTTPS_PROXY指向 Charles 的监听端口比如http://127.0.0.1:8888NO_PROXY暂时清空然后重新跑opencode auth login。在 Charles 里能看到两部分流量到 Antigravity 授权服务器和 token 端点的请求浏览器回跳时发出的http://127.0.0.1:34251/callback请求。如果第二条请求压根没有出现在 Charles 里说明它没走这个代理判断方向就要转向系统代理设置如果它出现在 Charles 里并且报错找不到主机那就坐实了“回环流量被代理带走”的问题。用抓包工具还有一个额外作用确认最终令牌请求里有没有携带正确的code。如果你看到 token 请求返回 400多半是 PKCE verifier 或 authorization code 已经失效重新跑一遍登录流程就能解决。5. 远程主机、容器、CI回调这条路走不通时的替代方案本地开发机上 OAuth 用起来最顺因为浏览器和 OpenCode 在同一台机器上回调天然能到达。但换到远程开发服务器、Docker 容器或者 CI 环境回调地址就会变成一个大麻烦。这一节讲的是在没有图形化浏览器的环境里怎么让 OAuth 依然可用。5.1 SSH 端口转发把远程的回调端口搬回本地浏览器远程开发机上没有浏览器但你可以让 OAuth 回调“穿越” SSH 隧道在本地浏览器的 127.0.0.1 上完成闭环。思路是在远程机器上启动opencode auth login它会监听远程机器的某个端口比如 8899。然后在本地机器上执行ssh -L 8899:127.0.0.1:8899 userremote-server这个命令把本地 8899 端口和远程 8899 端口打通。浏览器在授权完成后访问http://127.0.0.1:8899/callback请求会通过 SSH 隧道被转发到远程机器的 8899 端口OpenCode 就能收到回调。这里要注意两点。第一远程机器上同样要设置NO_PROXYlocalhost,127.0.0.1确保回调请求不会被远程机器上的代理变量带走。第二本地浏览器如果开了系统代理也要保证本地访问127.0.0.1时不走代理否则流量根本进不了 SSH 隧道。5.2 容器环境尽量用 host 网络模式或设备码登录Docker 容器里跑 OpenCode 的场景越来越多但容器默认的 bridge 网络有一个问题容器内监听的127.0.0.1:port和宿主机是不通的。你在宿主机浏览器里完成授权后回调请求到了宿主机端口但容器里根本没有服务在那个端口上连接被直接拒绝。最简单的方案是让容器使用 host 网络模式docker run --network host ...这样容器内的127.0.0.1就是宿主机视角下的127.0.0.1回调天然可达。如果因为安全和隔离要求不能开 host 网络那就用端口映射但要注意 OAuth 回调地址里写的是127.0.0.1映射出来的端口和容器内的端口必须对应好。如果 OpenCode 支持设备码登录device authorization grant那更适合容器环境终端显示一个用户码和一个授权 URL你在任意一台有浏览器的机器上打开 URL、输入用户码容器里的 OpenCode 自己轮询 token 端点不需要回调地址参与这基本是容器场景的最优解。5.3 CI 无人值守环境设备授权码与预置 TokenCI 里跑opencode auth login比较尴尬没有浏览器也没有人可以交互。两个可行方案。第一个是设备授权码方案。操作起来类似刚才说的容器场景CI 进程打印一个 URL 和用户码操作者在自己电脑上打开 URL 完成授权。这个方案适合有人盯着 CI 的场合比如发布流水线里的手动审批阶段。第二个是预置 refresh token。你提前在本地完成一次登录把生成的 refresh token 放到 CI 的环境变量或密钥管理服务里CI 启动时 OpenCode 直接用 refresh token 换取 access token。这个方案完全无人值守但要注意 refresh token 会过期需要在过期前重新生成并更新密钥。不要直接把 access token 放到 CI 里因为 access token 有效期短过期后 CI 任务就会失败而 refresh token 加刷新逻辑才是长久的做法。5.4 进阶用 Nginx 把 OAuth 回调“搬”到可控域名如果你处于一个比较严格的内网环境本地回环地址被禁用或者 OAuth 客户端要求回调地址必须是 HTTPS 域名那可以用 Nginx 反向代理把回调地址映射到你可控的域名上。大致的思路是在你有权配置 DNS 的域名比如auth.corp.example上把流量反代到内网开发机的回调端口server { listen 443 ssl; server_name auth.corp.example; location /callback { proxy_pass http://192.168.1.10:8899; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; } }然后在 Antigravity 控制台的 OAuth 回调地址白名单里把https://auth.corp.example/callback加进去。OpenCode 启动登录时让它使用这个回调地址而不是默认的 localhost。这个方案把 OAuth 回调变成了标准的七层网络请求不依赖回环地址也不容易被子网隔离、防火墙策略误伤。需要注意两点一是回调地址必须和 OAuth 客户端里注册的地址精确匹配多一个斜杠、少一个端口都会失败二是 Nginx 要配置好长连接参数和worker_connections否则多人同时在开发机上登录认证时连接数上限可能会成为新的瓶颈。6. 一点实操心得把认证这件事做成“可重复执行”的流程文章最后分享几个我自己的经验。这些经验不完全来自文档更多是在业务环境里反复踩坑后形成的习惯。第一个习惯是建立“最小排查顺序”。我在遇到登录问题时永远按照这个顺序检查先确认本地回调端口有监听再确认NO_PROXY包含127.0.0.1然后确认代理证书是否被信任最后才去怀疑 OpenCode 配置。按照这个顺序大部分问题在第二步就能解决根本走不到最后一步。第二个习惯是把代理配置和 OpenCode 配置分开管理。我不会把export HTTPS_PROXY...直接写死在~/.bashrc里因为开发机同时要处理内网通信、本地调试和外部 API 调用全局代理变量太容易误伤回环流量。我更倾向于写一个proxy.sh脚本只有在需要走代理时才手动 sourceexport HTTPS_PROXYhttp://proxy.corp.example:8080 export NO_PROXYlocalhost,127.0.0.1,::1这样既能保证登录时环境正确也不会让代理变量污染其他项目的运行。第三个习惯是及时看 auth 文件。登录成功之后我会顺手看一眼配置目录下的认证文件确认没有把 Token 提交到 Git 仓库也会检查文件权限是不是 600。CI 环境里我会把认证方式尽量改造成设备码或 refresh token 模式而不是尝试在流水线里模拟浏览器。第四个习惯是耐心看日志。OpenCode 这类 CLI 工具通常有调试日志选项环境变量或--verbose之类的参数能输出完整的 HTTP 请求细节。遇到玄学报错时打开调试日志跑一遍登录看到具体是哪个 URL 报错、返回什么状态码往往比一遍遍猜代理配置要高效得多。如果你也在代理网络里折腾 OpenCode 的 Antigravity Auth希望这篇文章能帮你少走几个弯路。配置这事的本质不复杂让该走代理的请求走代理让该回本地的请求回本地再把代理的证书信任问题解决掉登录自然就通了。