搞定 CLI 认证:4 种方案全方位详解
4 种重要的 CLI 认证方式、GitHub、AWS 和 AI 工具是如何实现它们的,以及你绝对不想踩的安全坑。
每个开发者 CLI 的第一个命令几乎都是 login。但每家 CLI 的认证方式都各不相同。
GitHub 展示一个验证码,并让你用浏览器去验证。AWS 用基于 PKCE 的 SSO 打开浏览器。Stripe 要你在仪表盘中确认配对码。新一代 AI 工具(Claude Code、OpenAI Codex CLI、Cursor)也各自选择了不同方式。
如果你要开发自己的 CLI,认证是必须优先考虑的事情之一。选错了,你百分百会收到反馈:要么是用户抱怨,要么是被安全审计,甚至同时发生。更何况,随着最近越来越多 AI 编码代理在自动调用 CLI 工具,安全风险变得更高——你不光要认证人类用户,也要管理自动进程的凭证。
下面这四种认证方式是你真的需要了解的、当前主流工具都怎么用它们、以及必须避免的常见错误。
四大认证方式速览
先快速对比一下:
| 方式 | 最适合场景 | 安全性 | 需要用浏览器? |
|---|---|---|---|
| OAuth 设备码流程 | 无头环境、SSH | 高 | 不需要(同一台机器上) |
| 基于浏览器的 OAuth(localhost 回调) | 本地开发 | 最高 | 需要 |
| API 密钥 / PAT | 自动化、CI/CD、快速原型开发 | 中等 | 不需要 |
| 客户端凭证 | 服务间/机器对机器 | 高 | 不需要 |
每种方案都有取舍,下文会详细介绍每一种的要点。
1. OAuth 设备码流程(RFC 8628)
就是 CLI 展示一个像 ABCD-1234 的验证码和一个 URL,然后让你在任意设备上用浏览器打开并输入验证码认证。
采用者: GitHub CLI(默认方式)、Azure CLI(通过 --use-device-code)、Vercel CLI(最新默认方案)、OpenAI Codex CLI(测试中可选)
流程说明
- 你运行
cli login - CLI 向认证服务器请求设备码,发送自己的
client_id和需要的 scope - 服务器返回三项内容:
device_code(内部标识)、user_code(你要输入的短码)、verification_uri(需要访问的页面) - CLI 展示验证码和 URL,同时开始每隔 5 秒轮询认证服务器
- 你在 任意 设备上打开 URL,输入验证码,完成认证(密码、SSO、密钥、MFA 都行)
- 你点确认 后,下一次轮询就会拿到 access token 和 refresh token
- CLI 存储这些 token,认证完成
为什么开发者喜欢它
核心卖点:无处不通用。SSH 到远端服务器?没问题。Docker 容器里?正常用。没有本地浏览器的云 IDE?一样可用。不需要认证机器本地就有浏览器。
而且企业级认证流程(SAML、OIDC、MFA)全都支持,因为所有敏感操作都在浏览器进行,终端端口从未见到你的密码。
安全性陷阱:容易被忽略的钓鱼风险
设备码流程最大问题就是钓鱼攻击。攻击者可以发起设备码请求,拿到一个合法验证码,然后诱骗你输入,实际上是给攻击者帐号授权了。这绝不是理论上的问题,有安全研究者已经验证了针对 AWS SSO 设备码流的钓鱼攻击。
这个问题严重到 AWS 已经更改默认设置。从 AWS CLI v2.22.0 开始,aws sso login 默认从设备码流程切换到了基于 PKCE 的授权码流程。设备码流仍然可选(通过 --use-device-code),但已非主路径。
同时,微软自己的租户 开始全部封禁设备码流程(依赖条件访问策略),强烈暗示他们也认为这是高风险认证方式。
所以现在出现了分化:Vercel 采纳 设备码流作为 2025 年 9 月以后的默认,而 AWS 转向 PKCE。可以看出,如果真打不开浏览器,设备码流还是很适合,但本地能开浏览器的话还是 PKCE 更安全。
而认证服务商也看到增长需求。Logto 已发布 v1.38.0(和 Logto Cloud 都支持)原生应用 OAuth 2.0 设备认证授权,直接能用在所有原生 app。对于开发 CLI 的同学,这很重要。RFC 8628 的细节(码过期、限流、轮询逻辑、Web 验证页 UX)比想象中复杂许多,有服务商托底会省掉不少坑,你只需要调用正确的 HTTP 接口即可。
RFC 技术细节
RFC 8628 有几点值得注意:
- 设备码
expires_in由认证服务器设置。RFC 的建议值为 1800 秒(30 分钟),但不是强制要求。 - 如果服务器没指定轮询
interval,客户端默认间隔 5 秒。 - 如遇
slow_down错误,每次轮询再增加 5 秒。 - 设备码必须一次性使用且迅速过期。
- 所有 token 交换都必须基于 HTTPS。
2. 基于浏览器的 OAuth(localhost 回调)
这是本地开发最常见的 CLI 认证方式。运行 login 后浏览器自动打开,用户完成认证,浏览器重定向回本地临时 HTTP 服务。现代实现都会加上 PKCE(发音像 "pixie"),防止部分被利用的漏洞。
采用者: Claude Code、gcloud CLI、Terraform CLI、AWS CLI v2.22+(SSO 默认带 PKCE)
流程说明
- 你运行
cli login - CLI 在随机本地端口启动临时 HTTP 服务(比如
http://127.0.0.1:8742) - CLI 用浏览器打开认证服务的授权端点,把这个本地回调 URL 设成 redirect_uri
- 你在浏览器认证(SSO、密码、密钥等)
- 认证服务将浏览器重定向到
http://127.0.0.1:8742/callback?code=XXXX&state=YYYY - 本地服务捕获 code,通过后端 HTTPS 交换 token
- 浏览器显示成功页面 “认证成功,可关闭标签页”
- CLI 存储 token,关闭本地 HTTP 服务
体验极其顺畅。不用复制码、不用输 URL,只是自动开关一个浏览器标签页。
适用场景及限制
这种方式仅当 CLI 能打开浏览器且能监听本地端口才有效。不适用以下场景:
- SSH 远程会话
- Docker 容器(除非做端口转发)
- CI/CD 流水线
- 无头服务器
- 某些公司受限环境
所以大多数默认浏览器 OAuth 的工具都会提供回退方案,一般是设备码流或 API 密钥。
三大常见安全漏洞
问题 1:监听 0.0.0.0 而不是 127.0.0.1
这是最常见也最严重的错误。如果你的回调服务监听所有网卡接口,任何同网络的机器都可以截取授权码。
很多 HTTP 服务库默认监听 0.0.0.0,实际生产线上已见到此坑。
问题 2:缺少 state 参数校验
state 参数是你的 CSRF 保护措施。如果没有它,攻击者可让你的 CLI 接受任意会话的授权码。
问题 3:未加 PKCE
如果授权码流程未加 PKCE(Proof Key for Code Exchange),授权码就可能被拦截重放。
在普通授权码流程中,一旦授权码被攻击者拦截(无论通过网络、还是通过分析重定向 URL),攻击者就能用它换取真正的访问 token。PKCE 机制要求授权和 token 交换必须同一客户端,避免码被滥用。
PKCE 机制流程:
- 开始流程前,CLI 生成随机高熵字符串
code_verifier - 用 SHA-256 哈希生成
code_challenge - 初始授权请求提交 code_challenge
- 换 token 时提交原始 code_verifier
- 认证服务器校验两者一一对应
攻击者即使截获授权码,也没有 code_verifier,无法完成 token 置换。
这也是 AWS CLI v2.22+ 将 SSO 默认从设备码流切换到 PKCE 的主因。只要浏览器和 CLI 在同一台机器,浏览器 OAuth + PKCE 是最优解:既有极好体验,又有最高安全级别,无钓鱼隐患。如果浏览器无法和 CLI 同机(SSH、容器、远程开发),才需要设备码流,但本地开发场景远没那么多。
3. API 密钥与个人访问令牌(PAT)
最简单粗暴的方式。你在网页版后台生成一串 token,粘贴到 CLI 配置或环境变量,完事。
采用者: Stripe CLI(可选方式)、npm、pip、大多数 AI 工具默认或兜底方案(Claude Code 用 ANTHROPIC_API_KEY,OpenAI 工具用 OPENAI_API_KEY,Aider 超多)
流程说明
- 登录服务的 Web 后台
- 找到设置 → API Keys/Personal Access Tokens/Developer Tokens
- 生成新密钥,通常是带前缀的长随机串(比如
sk_live_、ghp_、npm_) - 存到配置文件(
~/.config/stripe/config.toml、~/.aws/credentials)或环境变量
CLI 启动时读取并在 API 请求中加到 Authorization 头。
为什么它还能流行
自动化场景 API 密钥难以替代:CI/CD、容器、脚本、计划任务都容易集成环境变量。不依赖浏览器,没有交互,无需刷 token。
尤其 AI 编码代理整合流程,API key 基本是最佳选择。Claude Code 或 Cursor 这种 API 调用,只需一个环境变量就能打通。
安全风险
- 泄露。 API 密钥经常意外暴露在 git 提交、日志、异常消息、CI 输出中。GitHub 每年都检测到一百万以上泄漏的 token。
- 权限过大。 大多数 API 密钥授权极广,被泄可造成巨大破坏。
- 没 MFA。 API 密钥绕过 你精心配置的多因素认证。
- 难以轮换。 每次换新密钥都得全部地方更新团队协作非常头疼。
进阶做法:临时 token 交换
更安全用法:将长期存活的密钥换成短暂有效的临时 token。
AWS 最早普及了 STS(安全令牌服务):长期凭证只用来换取一小时左右有效的临时凭据。aws-vault 这类工具全自动处理。
即便初始方案是 API 密钥,建议也补上这套模式。即使密钥被盗,损失窗口从“被发现前”缩短到“一小时内”。
4. 客户端凭证流
这是 OAuth 2.0 专为机器到机器设计的流程,适用于服务间自动认证,无需人工介入。
适用于: CI/CD 流水线、后台服务、自动化工具
流程说明
服务端将 client_id 和 client_secret 直接发给认证服务器,换取短时有效的访问 token。无需浏览器、无需用户参与、无需重定向。
适用场合
仅用于:
- 程序/机器人需要认证
- CI/CD 流水线环境
- 需要无人值守自动访问
- “用户” 实际上是应用而不是人
切忌当做人类用户认证。 不支持 MFA、SSO,也没有任何交互式校验。
主流 CLI 认证方式一览
以下为当前文档和源码实际情况。很多文章说错了,因为这些工具在不断调整默认设置。
| CLI 工具 | 默认认证 | 兜底方式 | Token 存储 |
|---|---|---|---|
GitHub CLI (gh) | 设备码流+浏览器 | PAT(--with-token)、环境变量(GH_TOKEN) | OS 密码库(兜底:明文文件) |
| AWS CLI v2 | PKCE 授权码流(SSO) | 设备码(--use-device-code)、证书文件 | ~/.aws/sso/cache/ |
Azure CLI (az) | Windows:WAM;Linux/macOS:浏览器授权码流 | 设备码(--use-device-code) | ~/.azure/msal_token_cache.* |
| Vercel CLI | 设备码流(2025.9 新默认) | API token(--token/环境变量) | ~/.local/share/com.vercel.cli/auth.json |
| Stripe CLI | 浏览器配对流 | API key(--interactive、--api-key 或环境变量) | ~/.config/stripe/config.toml |
| gcloud CLI | 浏览器 OAuth | --no-browser 手动授权流程 | ~/.config/gcloud/ |
| Claude Code | 浏览器 OAuth | API key(环境变量、apiKeyHelper) | OS 密码库 / ~/.claude/.credentials.json |
| OpenAI Codex CLI | 浏览器 OAuth | 设备码(测试版)、API key | ~/.codex/auth.json/OS 密码库 |
| Terraform CLI | 浏览器 OAuth | 粘贴 token | ~/.terraform.d/credentials.tfrc.json |
总趋势非常明显:本地开发首选浏览器 OAuth + PKCE,无头环境备选设备码流,自动化工作流主用 API key。 只要有浏览器,PKCE 正在成为最安全首选。
Token 存储:推荐做法与大坑警示
认证再安全,只要 token 存错地方,一样危险。
正解:操作系统密码库
所有主流操作系统自带加密凭证库:
- macOS: 钥匙串(GitHub CLI、Claude Code 都用这个)
- Windows: Credential Manager
- Linux: Secret Service API(GNOME Keyring、KDE Wallet)
这些支持系统级加密、授权管理,还能集成硬件安全。CLI 无需自造加密。
备选方案:加密配置文件
没有密码库可用(容器、最小化系统)时,请用权限严格的加密配置文件:
一定要避免的
明文文件。 看似没啥人会这么做,实际上仍然有不少工具这样存。明文 token 文件对用户本地所有进程、所有备份工具、甚至机子被临时外借时都曝光。
长期存储用环境变量。 环境变量在进程列表可见,经常被 crash 报告、子进程意外泄露。CI/CD 场景问题小(CI 平台会加密和动态注入),本地开发极其危险。
浏览器 localStorage。 CLI 有 Web 组件切记别把 token 放 localStorage。一次 XSS 整个泄漏。
Token 生命周期管理
访问令牌(Access Token)
建议短时效。一般一小时以内。过期时 CLI 应自动刷新,无需用户反复登录。
刷新令牌(Refresh Token)
刷新 token 允许你在不重新认证情况下获取新 access token。它们寿命较长(通常为几天甚至数月),是攻击者首选目标。
刷新令牌轮换最佳实践
现代认证体系建议每次用完刷新 token 就换一个:
- CLI 用刷新 token 换新 access token
- 认证服务返回新 access 与新刷新 token
- 老的刷新 token 立即失效
- CLI 保存新 token
这样一旦刷新 token 被盗,但你已经使用过了,服务方可发现“两次用同 token”,直接失效全部 family,攻击者和你都得重登,但能防止长期被拿走。
常见错误及代码示例
1. 回调服务监听全网接口
上文已详述,只绑定 127.0.0.1,千万别用 0.0.0.0。
2. 记录 token 到日志
远比你想象更常见。调试日志、异常处理打印请求头、或 verbose 模式下全量日志。
3. 凭据打包进镜像层
Docker 镜像不是密钥仓库,每一层都能被提取。
4. 不优雅处理 token 过期
Token 处理中途过期时别直接抛 401 crash。应该尝试刷新,只在 refresh token 也过期时要求重认证。
5. 忽略最小权限原则
只需要 repo:read 就别请求 admin:* scope。这一原则对 OAuth scope、API key 权限都适用。
AI 代理用 CLI 时尤其关键,你不想 AI agent 有删除仓库权限,仅仅因为它只是想读代码。
AI 代理引发的新挑战
为什么 2026 和 2023 不一样?CLI 不再只服务人工命令,AI 编程助手(如 Claude Code、Codex、Cursor agent)已在自动程序化调用 CLI。带来如下新问题:
权限委托。 比如 Claude Code 帮你执行 gh pr create,用的是你的 GitHub 凭证。但 AI agent 该完全继承你的全权限吗?最小权限原则 NO,但目前大部分工具无法细粒度限制 agent 权限。
凭证暴露。 如果 API key 存在环境变量,任意进程都能拿到,包括 AI agent 的所有子进程。Claude Code 借助 apiKeyHelper 实现按需生成短时 token,但不是所有都这样做。
无头 agent 场景的认证。 Agent 跑沙箱环境无法开浏览器。设备码流能用(人类在别设备批准),但绝大多数 Agent 仍喜欢零交互的 API key。
审计追踪。 AI agent 用你的凭证调 API,后台的 audit log 就只显示“你自己”做的。不区分“你本人操作”还是“AI 代你操作”。
这是个快速演变中的领域。当前最佳实践:
- agent 用流程一定要设最小权限专用 token
- 优先临时凭据(短期 token,不是长期 API key)
- agent 专用凭证与个人主凭证严格分离
- 持续监控 API 调用异常模式
认证方案选择建议
需要选方案?直接参考:
“用户都是本地开发者” → 浏览器 OAuth + PKCE(极好安全与最佳体验)
“CLI 必须兼容 SSH 会话和容器场景” → 主选浏览器 OAuth,兜底设备码流
“无人工参与的 CI/CD 环境” → 客户端凭证流,或者 Scope API key
“要最快实现方案” → API key(后续再补 token 轮换)
“企业客户要 SSO + MFA” → 任意 OAuth 方案(设备码流或浏览器流都支持企业全套认证)
“AI agent 会调用 CLI” → 支持 API key(适合 agent 集成)+ 浏览器 OAuth(适合人工),并配置最小权限和短期 token
FAQ 常见问题
设备码流程安全吗?
对大多数攻击安全,但有已知钓鱼风险。攻击者可生成设备码诱导用户授权。AWS 因此已切换 SSO 默认为 PKCE。如果无头环境不能用 PKCE,设备码流还是最佳也没别的。但请务必意识钓鱼问题。
能把 token 存到环境变量里面吗?
CI/CD 环境可以,因为 CI 平台会加密落盘、动态注入。开发本地环境请别用。用 OS 密码库。环境变量常被进程列表、日志、子进程泄露。
API key 跟 personal access token 有啥区别?
本质区别很小,两者都是长期有效的授权凭证。区别主要在组织方式:API keys 多用于“项目/应用”,PAT 通常跟个人账户绑定。有些服务两者说法混用。
凭证需要多久轮换一次?
Access token:建议 1 小时或更短(刷 token 流程自动)。Refresh token:每次用完自动轮换(服务端处理)。API key:至少 90 天一轮,或一旦有泄露嫌疑就立即。实际大多数团队只出事才会换 API key,这属于应急而非合规安全。
Docker 容器该如何搞认证?
推荐顺序:
- 设备码流 适合交互(支持异设备浏览器批准)
- 环境变量运行时注入(
docker run -e API_KEY=${API_KEY})适合 CI/CD - 卷挂载凭据文件(
docker run -v ~/.config/tool:/root/.config/tool:ro)适合本地开发
切记切记切记,千万别 bake 凭据进镜像!
MCP(模型上下文协议)认证怎么做?
MCP 是 AI agent 连接工具/服务的新标准。额外认证要求:agent 需自己的凭证连 MCP Server,然后 MCP Server 再有下游 API 凭证。目前 MCP 多通过 API key 或 OAuth token 配置,标准还在快速演变,未来或会大不一样。
CLI 认证体系变化极快。两年前的最佳实践(设备码流为主,明文 token 文件)现已被淘汰。如果你正在为 CLI 加认证,强烈建议主推浏览器 OAuth + PKCE(人用)、API key(自动化用),并规划未 来你的主要用户可能是 AI agent。

