- 人工智能
- AI 应用
- AI Agent
- 代码智能体
- 开发工具
- CLI
- MCP Clients
【免费下载链接】grok-build
SpaceXAI's coding agent harness and TUI. Fullscreen, mouse interactive, extensible.
本篇指南以 grok-build 的官方用户手册 02-authentication.md 为骨架,结合仓库中xai-grok-shell与xai-grok-auth的认证实现源码,系统讲解 grok 的六种登录方式(浏览器 OAuth、API Key、企业 OIDC、外部认证提供方、设备码)以及凭据存储、自动刷新、热重载与认证优先级等运行机制。读完本文,你将能够为本地开发、CI/CD 与无浏览器环境分别选择正确的认证方案,并能在认证失败时借助日志与源码快速定位问题。
认证方式总览
grok 支持以下认证方法,覆盖从个人电脑到企业内网、从交互式终端到无人值守 CI 的全场景:
| 认证方式 | 适用场景 | 入口 |
|---|---|---|
| 浏览器登录(默认) | 本地交互使用,首次启动自动触发 | grok、grok login |
| API Key | CI/CD、自动化脚本、无浏览器环境 | XAI_API_KEY环境变量 |
| OIDC(企业 SSO) | 通过自有 IdP(Okta、Azure AD、Auth0)登录 | config.toml/GROK_OIDC_*环境变量 |
| 外部认证提供方 | 沙箱 VM、CI Runner、隔离网络,由外部二进制托管认证 | [auth] auth_provider_command |
| 设备码流程 | SSH 会话、Docker、远程 VM,本地无浏览器 | grok login --device-auth |
从源码结构看,这些方法统一由xai-grok-shellcrate 的 auth 模块 管理:flow.rs负责交互式登录流程的路由,config.rs定义各认证方法的配置结构,manager.rs负责凭据的读取与持久化,external_auth.rs专门执行外部认证提供方。
浏览器登录(默认)
首次启动时直接运行:
grokgrok 会自动打开浏览器跳转到 SpaceXAI 的 OAuth 授权页(auth.x.ai)完成认证。成功后:
- 凭据写入
~/.grok/auth.json,并在后续会话间复用; - 访问令牌在后台自动刷新(涉及 OIDC 时通过保存的
refresh_token静默续期); - 当令牌无法刷新时,grok 会提示你重新登录;
- 服务端未提供过期时间的凭据,回退为30 天的有效期(源码 auth/model.rs 中通过
TOKEN_TTL常量实现该回退逻辑)。
凭据存储与安全
令牌保存在~/.grok/auth.json(MCP OAuth 令牌则在~/.grok/mcp_credentials.json),Unix 下以属主独占权限(0600)写入。注意:任何对这两个路径拥有文件系统访问权限的人都能直接使用这些凭据,因此请遵循:
- 优先启用全盘加密(FileVault、BitLocker、LUKS 或同类方案);
- 不要把
auth.json、mcp_credentials.json复制进共享目录、工单或聊天记录; - 在多用户主机上,让
$HOME/$GROK_HOME保持仅自己账户可访问。
另外,从仓库中的锁测试(flock_wait_tests.rs)可以看出,auth.json的并发写入由auth.json.lock文件锁保护,避免多个进程(如grok login与正在运行的 TUI)同时写文件导致损坏。
重新登录与登出
切换账号或解决认证问题:
grok logingrok login会重新走一遍登录流程并替换缓存的会话。默认打开浏览器、通过 SpaceXAI OAuth(auth.x.ai)登录,也可以传旗标选择其他流程:
| 旗标 | 说明 |
|---|---|
--oauth | 通过 SpaceXAI OAuth 登录(auth.x.ai)。这是默认行为,旗标可省略。 |
--device-auth(别名--device-code) | 使用设备码流程登录,适用于无头或远程环境。 |
登出使用grok logout,该命令不接受任何旗标,直接清除缓存的凭据。
源码层面,这两个旗标被映射为LoginTransportOverride枚举(flow.rs):--oauth强制走 loopback 回调流程,--device-auth强制走 RFC 8628 设备流程;两者同时设置时--oauth优先。
API Key(CI/CD 或自动化)
对于 CI/CD、自动化或没有浏览器访问权限的环境,可以在 console.x.ai 控制台创建 API key 后通过环境变量注入:
export XAI_API_KEY="xai-..." grok关键行为:
- API key 只在没有活跃会话令牌时作为回退使用;
- 如果你已经交互式登录过,存储的会话令牌优先于 API key;
- 想回退到 API key,执行
grok logout或删除~/.grok/auth.json。
在源码中,XAI_API_KEY属于AuthMode::ApiKey路径。仓库还提供了企业级管控开关:设置GROK_DISABLE_API_KEY_AUTH后,xai.api_key认证方法既不会被宣传也不会被接受(config.rs),防止 API key 绕过企业 IdP 登录——该环境变量锁定在运行期读取,用户层config.toml无法将其关闭。此外,[auth] preferred_method = "api_key"可以把自动认证钉死在 API key 上,此时所有自动 OIDC 路径(devbox 铸造、浏览器登录、外部认证提供方)均被 fail-closed 阻断(config.rs)。
OIDC(企业 SSO)
OIDC 让开发者通过你们自己的身份提供商(IdP)——例如 Okta、Azure AD、Auth0——完成认证,而不是使用 grok.com 账号。
1. 在 IdP 中注册一个公共客户端
- 授权类型:Authorization Code with PKCE(Proof Key for Code Exchange);
- 回调 URI:
http://127.0.0.1/callback——这是一个 loopback 地址。grok 在登录时绑定一个随机端口,大多数 IdP 按照 RFC 8252 将 loopback 回调视为与端口无关; - 不需要 client secret,PKCE 取代了它。
2. 配置 CLI
通过配置文件(推荐):
# ~/.grok/config.toml [grok_com_config.oidc] issuer = "https://acme.okta.com" client_id = "0oa1b2c3d4e5f6g7h8i9"或通过环境变量:
export GROK_OIDC_ISSUER="https://acme.okta.com" export GROK_OIDC_CLIENT_ID="0oa1b2c3d4e5f6g7h8i9"还可以覆盖 API 端点指向你自己的代理:
export GROK_CLI_CHAT_PROXY_BASE_URL="https://grok-proxy.acme.com/v1"3. 运行grok
CLI 通过{issuer}/.well-known/openid-configuration自动发现端点,打开 IdP 登录页,并把令牌写入~/.grok/auth.json。令牌通过保存的refresh_token静默自动刷新。
可选字段
| 字段 | 默认值 | 说明 |
|---|---|---|
scopes | ["openid", "profile", "email", "offline_access", "api:access"] | offline_access开启静默令牌刷新 |
audience | 无 | 某些 IdP(如 Auth0)要求设置 |
源码印证:OidcAuthConfig结构体(config.rs)正是[grok_com_config.oidc]的序列化映射,默认 scopes 由default_oidc_scopes()函数定义(config.rs);GROK_OIDC_SCOPES(逗号分隔)与GROK_OIDC_AUDIENCE也可作为环境变量覆盖这两项。认证作用域 key 的格式为{issuer}::{client_id},用于在auth.json中区分不同登录来源(config.rs)。
需要留意:OIDC 登录始终走 loopback 流程——企业 IdP 通常不提供设备码端点,因此--device-auth在企业 OIDC 配置下会自动回退到 loopback(flow.rs)。
外部认证提供方(External Auth Provider)
当浏览器登录不可行时——例如沙箱化 VM、CI Runner、隔离网络——可以把认证委托给一个外部二进制或脚本。
工作原理
+--------------+ sh -c +------------------------+ | Grok |-------------->| your auth binary | | | | | | reads |<-- stdout ----| prints token | | auth.json | | | | | (stderr) | prints status/URLs |--> surfaced to user +--------------+ +------------------------+流程共五步:
- grok 通过
sh -c "<command>"运行你的命令; - 你的二进制执行所需的任意认证流程(SSO、设备码、证书交换);
- stderr携带人类可读的输出,如登录 URL 与状态消息。grok 读取 stderr 并展示给用户;在 TUI 中,stderr 里第一个
https://URL 会被转换为可点击的登录链接; - stdout被 grok 捕获并保存为访问令牌;
- 退出码 0 = 成功;非零退出码 = grok 回退到交互式登录。
stdout / stderr 契约
| 流 | 打印什么 | 谁看到 |
|---|---|---|
| stdout | 只有令牌,别无其他 | grok(解析后存入 auth.json) |
| stderr | 登录 URL、状态消息、错误 | 用户(grok 读取 stderr,并在 TUI 中把登录 URL 显示为可点击链接) |
不要在 stdout 上打印除令牌以外的任何内容——不要打印进度消息,不要打印调试输出。grok 读取 stdout、裁剪首尾空白后将其解析为令牌。
stdout 令牌格式
裸字符串——直接输出原始令牌:
eyJhbGciOiJSUzI1NiIs...JSON——可携带 refresh token、过期时间与 issuer:
{"access_token": "eyJhbGciOi...", "refresh_token": "ref-tok", "expires_in": 3600, "issuer": "https://idp.example.com"}如果你的令牌会过期、并希望 grok 在过期前自动重新运行你的二进制,请使用 JSON 格式。JSON 字段如下:
| 字段 | 是否必需 | 含义 |
|---|---|---|
access_token | 是 | grok 发送给 xAI API 的 Bearer 令牌 |
refresh_token | 否 | 仅存储备查。grok 通过重新运行你的二进制来刷新,而不是使用 OAuth refresh grant |
expires_in | 否 | 令牌生命周期(秒);启用过期前的主动刷新 |
issuer | 否 | 标识令牌的签发方 |
解析实现细节(token_output.rs):只要输出以{开头,就会被当作 JSON 令牌负载并要求能解析出非空access_token;否则视为裸字符串令牌(JWT 与不透明令牌不会以{开头,因此{"error":"expired"}这类错误对象永远不可能被误当成 Bearer)。非零退出码、非 UTF-8 输出、空 stdout、空access_token或非法 JSON 负载一律判为失败——畸形输出 fail closed,绝不会被送上线路。
配置
通过配置文件:
# ~/.grok/config.toml [auth] auth_provider_command = "/usr/local/bin/my-auth-provider" auth_provider_label = "Acme Corp" # 可选 -- 自定义 TUI 登录按钮文案 auth_token_ttl = 3600 # 可选 -- 令牌生命周期(秒)或通过环境变量:
export GROK_AUTH_PROVIDER_COMMAND="/usr/local/bin/my-auth-provider" export GROK_AUTH_PROVIDER_LABEL="Acme Corp" export GROK_AUTH_TOKEN_TTL=3600源码确认:GrokComConfig中auth_provider_command、auth_provider_label、auth_token_ttl三个字段分别由同名环境变量直接填充(config.rs)。其中auth_token_ttl用于给输出裸字符串令牌(没有expires_in)的外部提供方合成expires_at,从而让主动刷新机制生效。
令牌刷新:GROK_AUTH_EXPIRED双契约
grok 在两种不同契约下运行你的二进制,GROK_AUTH_EXPIRED环境变量就是区分信号。每次运行都会完全替换已存储的凭据,因此每次调用(包括刷新)都要输出相同的 JSON 字段(如issuer)。
GROK_AUTH_EXPIRED=1—— 无头刷新(headless refresh)。grok 在为自己已持有的凭据重新铸造令牌:即将过期的轮换,或服务端已拒绝的令牌。此时无人观看。stdin 已关闭,你的 stderr 会被吞掉,二进制只有几秒钟时间,超时即被杀。请静默铸造令牌或直接非零退出——绝不阻塞。变量未设置 —— 登录(sign-in)。
grok login、登录界面,或无头刷新铸造失败后 grok 发起的升级登录。此时有用户在等待,你的 stderr 会送达用户,并且你有300 秒——足够完成一次浏览器往返或一次设备码输入。
一个同时处理两种契约的参考脚本:
#!/bin/sh if [ "$GROK_AUTH_EXPIRED" = "1" ]; then # 无头模式:只做静默刷新。当你的 SSO 会话已过期且只有用户能续期时, # 快速拒绝是正确的答案。 echo "Refreshing token..." >&2 TOKEN=$(my-company-auth --refresh --silent) || exit 1 else echo "Authenticating via Acme Corp SSO..." >&2 TOKEN=$(my-company-auth --login --interactive) fi if [ -z "$TOKEN" ]; then echo "Authentication failed" >&2 exit 1 fi echo "{\"access_token\": \"$TOKEN\", \"expires_in\": 3600}"当无头刷新拿不到令牌时,grok 会停止把已存储凭据视为可用,转而启动登录流程——与你从未登录过的机器上触发的是同一个流程,此时你的二进制 stderr 会显示出来,设备码 URL 或浏览器提示能到达你。在GROK_AUTH_EXPIRED=1时快速退出正是让这次交接变快的关键;阻塞的二进制只会让你每次启动都白白等完刷新超时。会话中途,则该轮请求失败并出现重新认证提示,/login会以交互方式重新运行你的二进制。
源码级时间约束:无头刷新的硬性超时是 7 秒(EXTERNAL_AUTH_REFRESH_TIMEOUT,见 external_auth.rs),并通过进程组杀手在超时时将二进制及其子进程一并终止;超时消息会记录为 "timed out (a timeout usually means it needs interactive sign-in)"(external_auth.rs)。交互式登录的上限则是 300 秒。
一个边界情形(仅 leader 模式):--leader,或[cli] use_leader = true(默认关闭)。在没有任何凭据的情况下,leader 会在启动后的后台额外尝试一次,而这次运行的GROK_AUTH_EXPIRED未设置,与登录无异。能够自主铸造令牌的二进制(服务账号、keytab、挂载令牌)在此次尝试中成功,会话自我修复;必须提示用户的二进制则最多等待 300 秒的登录上限——没有人在等它,登录界面早已弹出,而且这次运行的 stderr 会写入~/.grok/leader.log而不是直接给你看。
环境变量汇总
| 变量 | 说明 |
|---|---|
GROK_AUTH_PROVIDER_COMMAND | 你的认证二进制路径 |
GROK_AUTH_PROVIDER_LABEL | TUI 登录界面上的显示名(如 "Acme Corp") |
GROK_AUTH_TOKEN_TTL | 令牌生命周期(秒),用于没有expires_in的裸字符串令牌 |
GROK_AUTH_EXPIRED | 无头刷新时设为1:不要提示,也不要交回缓存的令牌。登录时未设置(有用户在场) |
GROK_AUTH_EARLY_INVALIDATION_SECS | 过期前主动刷新的提前量(默认 300 秒) |
仓库中还提供了完整的端到端测试可以对照学习:外部认证提供方的符合性测试在 external_auth_conforming_provider.rs,凭据过期场景在 external_auth_expired_credential.rs,auth_provider_command的 E2E 验证在 test_auth_provider_command_e2e.rs。
设备码流程(Device Code Flow)
适用于本地没有可用浏览器的无头环境(SSH 会话、Docker 容器、远程 VM):
grok login --device-auth # 或: grok login --device-code该命令会在终端打印一个 URL 和验证码。在任意设备上打开 URL、输入验证码即可完成认证,grok 会轮询直到登录被确认。
设备码流程同样可以通过外部认证提供方自行实现,以获得完全控制。
流转决策的优先级(flow.rs)——设备流程是否启用按以下层级解析:CLI 旗标(--oauth/--device-auth)>GROK_LOGIN_DEVICE_FLOW环境变量 >[auth] login_device_flow配置 > 远端特性开关(grok_build_login_device_flow)> 默认的 loopback 流程。远端特性开关的拉取还有 2 秒超时兜底,慢速网络不会卡死登录(flow.rs)。
自动凭据刷新
grok 会自动刷新过期的凭据,触发条件有三类:
- 过期前:如果认证提供方返回了
expires_in(JSON 输出)或你设置了auth_token_ttl,grok 会在过期前约 5 分钟重新运行认证二进制; - 认证错误:服务端返回 401 Unauthorized 时,grok 刷新凭据并重试该请求;
- OIDC:若存在
refresh_token,grok 通过你的 IdP 静默刷新,不再重新打开浏览器。
刷新提前量可以调节:
# 过期前 5 分钟刷新(默认) export GROK_AUTH_EARLY_INVALIDATION_SECS=300 # 关闭主动刷新缓冲:仅在过期时或收到 401 时刷新(设为 0) export GROK_AUTH_EARLY_INVALIDATION_SECS=0源码印证:默认提前量常量DEFAULT_EARLY_INVALIDATION_SECS: u64 = 300(5 分钟)定义在 auth/model.rs,实际判断Utc::now() >= (expires_at - buffer)在is_expired_with_buffer(auth/model.rs);对没有expires_at的凭据则用创建时间加上 TTL 推算。无头刷新与 401 触发刷新的路径在 external_auth.rs 中:命令以GROK_AUTH_EXPIRED=1启动,7 秒超时,成功则日志记录 "auth: external auth provider returned fresh token",且新凭据会保留旧凭据中的用户资料字段(如 ZDR 标志、组织 ID),见refresh_with_command及其测试(external_auth.rs)。
热重载(Hot Reload)
grok 会自动感知~/.grok/auth.json的变化。如果你在外部更新了凭据(例如用脚本写入新令牌),无需重启,grok 会在下一次 API 调用时直接使用新凭据。从架构上看,AuthCredentialProvider::snapshot()在每次取凭据前都会做一次廉价的磁盘重读(见 auth_provider.rs 与 xai-grok-shell/src/auth/credential_provider.rs),因此来自兄弟进程(grok-desktop、grok login)的更新能即时可见。
认证优先级(Auth Precedence)
grok 对每个请求按以下顺序解析凭据(从高到低):
- 每个模型的
api_key或env_key—— 在config.toml的[model.<name>]下设置。只要存在即生效(即 BYOK 模式,参见 11-custom-models.md); - 活跃的会话令牌—— 通过浏览器、OIDC/OAuth2 或外部提供方登录获得,存储于
~/.grok/auth.json; XAI_API_KEY—— 没有活跃会话令牌时的回退。
当配置了多个登录流程时,grok 按以下顺序(从高到低)用第一个可用来源填充会话令牌:
- 外部认证提供方(
auth_provider_command); - 企业 OIDC—— 通过
config.toml的[grok_com_config.oidc]或GROK_OIDC_ISSUER/GROK_OIDC_CLIENT_ID环境变量配置; - SpaceXAI OAuth2 浏览器登录—— 默认方式。
会话期间,中途的所有刷新都由当时活跃的方式负责处理。
相关设置
需要注意:编码数据共享(Settings 中的 "Coding data, retention, and training",/privacy命令可打开)不会改变以下这些配置旋钮:
| 设置 | 如何设置 |
|---|---|
[features] telemetry | config.toml或GROK_TELEMETRY_ENABLED |
[telemetry] trace_upload | config.toml或GROK_TELEMETRY_TRACE_UPLOAD |
| 外部 OpenTelemetry | GROK_EXTERNAL_OTEL/[telemetry] otel_*。参见 监控用量 |
在企业(团队)账号下,只有团队管理员能修改编码数据共享;团队管理员还可以为团队启用或禁用 Zero Data Retention(ZDR)。ZDR 开启后,编码数据共享完全不可修改——设置项的值会显示为ZDR。
更多内容参见 监控用量 与 配置。
故障排查
调试日志
设置RUST_LOG可以控制文件日志与无头模式 stderr 输出的详细程度(TUI 的屏幕内 tracing 面板使用固定过滤条件,忽略RUST_LOG)。TUI 中文件日志默认为DEBUG;无头模式(-p)下RUST_LOG默认为off,只输出答案——设置RUST_LOG=error(或更宽)即可在 stderr 看到日志。
TUI 中可用GROK_LOG_FILE指定绝对路径写日志:
GROK_LOG_FILE=/tmp/grok.log RUST_LOG=debug grok tail -f /tmp/grok.logGROK_LOG_FILE被当作字面文件路径处理。相对值(如1)会在当前目录写一个名为1的文件。
无头模式下日志走 stderr,可重定向到文件:
RUST_LOG=debug grok -p "hello" 2> /tmp/grok.log常见日志消息
这些日志文本与源码 external_auth.rs 中的tracing调用一一对应,可作为排查线索:
| 日志消息 | 含义 |
|---|---|
auth: running external auth provider (headless refresh)/(interactive login) | grok 正在运行你的二进制,以及是哪种契约 |
auth: external auth provider returned fresh token | grok 已解析并存储令牌 |
auth: external auth provider failed | 二进制非零退出或 stdout 为空 |
auth: external auth provider timed out (likely needs interactive auth), killing | 二进制在超时前未退出,已被终止 |
auth: failed to start external auth provider | 命令无法生成(二进制不存在) |
常见修复
- "Authentication failed"—— 执行
grok logout清除缓存的凭据,再执行grok login重新登录; - 令牌过期太快—— 设置
auth_token_ttl,或在认证提供方的 JSON 输出中返回expires_in; - OIDC 重定向失败—— 确认你的 IdP 允许 loopback 回调 URI(
http://127.0.0.1/callback); - 找不到外部认证提供方—— 检查
auth_provider_command的路径是否正确、二进制是否可执行。
延伸阅读
- 完整配置参考:26-config-reference.md
- 配置分层与环境变量详解:05-configuration.md
- 每模型 API key 与 BYOK:11-custom-models.md
- 认证实现源码:xai-grok-shell/src/auth/(
config.rs、flow.rs、external_auth.rs、token_output.rs、model.rs) - 认证凭据提供者抽象:xai-grok-auth/src/auth_provider.rs
- 端到端测试:external_auth_conforming_provider.rs、external_auth_expired_credential.rs、test_auth_provider_command_e2e.rs
- 人工智能
- AI 应用
- AI Agent
- 代码智能体
- 开发工具
- CLI
- MCP Clients
【免费下载链接】grok-build
SpaceXAI's coding agent harness and TUI. Fullscreen, mouse interactive, extensible.
相关推荐
WeKan 登录与认证体系深度解析:从客户端登录表单到 OIDC、LDAP、SAML 企业级认证
WeKan 登录与认证体系深度解析:从客户端登录表单到 OIDC、LDAP、SAML 企业级认证 导读 本文以 READMELoginSignUp.md htt
后端前端协同办公Remix 认证原语实战:使用 remix/auth 组合凭据认证与 OAuth/OIDC 外部登录
Remix 认证原语实战:使用 remix/auth 组合凭据认证与 OAuth/OIDC 外部登录 导读 remix/auth 是 Remix 框架中一套可组
后端前端Web框架grok-build 0.2.34:`grok login` 默认切换 Device Code 登录流,并修复认证刷新卡死
grok build 0.2.34: grok login 默认切换 Device Code 登录流,并修复认证刷新卡死 版本要点速览 :grok build
人工智能AI 应用AI Agent代码智能体开发工具CLIMCP Clients
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考