fix(oidc): 恢复 grok-cli:access 并支持批量重铸

补回 mint scope 中的 grok-cli:access,铸造后校验 JWT scope,
避免 cli-chat-proxy 返回 grok-cli-token-auth-required。
新增 remint_cli_scope.py,基于已有 sso 覆盖写回缺 scope 的 CPA auth;
同步更新 cpa/schema 文档说明 referrer 与 scope 双重要求。
This commit is contained in:
chaos committed 2026-07-15 10:12:17 +08:00
1 parent 7d6d52ac5d
commit bc5ad63755
4 files changed
+324 -5

No files matched your search

+25 -2
View File
@@ -29,11 +29,14 @@ AUTHORIZE_URL = f"{ISSUER}/oauth2/authorize"
# 兼容保留旧固定端口常量,仅作 fallback
REDIRECT_URI_LEGACY = "http://127.0.0.1:56121/callback"
REDIRECT_URI = REDIRECT_URI_LEGACY
# 对齐官方 docs + discovery:去掉二进制中已不出现的 grok-cli:access
# cli-chat-proxy 要求 access_token.scope 含 grok-cli:access,否则:
# WKE=unauthorized:grok-cli-token-auth-required
# 2026-07 一度误删该 scope(对齐 discovery),导致铸造成功但调用 403。
SCOPE = (
"openid profile email offline_access "
"api:access conversations:read conversations:write"
"grok-cli:access api:access conversations:read conversations:write"
)
GROK_CLI_SCOPE = "grok-cli:access"
GROK_REFERRER = "grok-build"
# 对齐官方 stable CLI(2026-07-14:0.2.101)
GROK_VERSION = "0.2.101"
@@ -503,6 +506,26 @@ def _run_sso_flow(
log(f"WARN {msg}")
else:
log("access_token referrer=grok-build ok")
# cli-chat-proxy 的 Grok CLI gate:缺 grok-cli:access 会直接 403
scope_text = ""
try:
scope_text = str(jwt_payload(token.access_token).get("scope") or "")
except Exception:
scope_text = ""
scopes = set(scope_text.split())
if GROK_CLI_SCOPE not in scopes:
msg = (
f"access_token 缺少 {GROK_CLI_SCOPE} "
f"(scope={scope_text or '(empty)'});"
"cli-chat-proxy 会返回 grok-cli-token-auth-required"
)
if require_referrer:
raise OAuthCodeError(msg)
log(f"WARN {msg}")
else:
log(f"access_token scope 含 {GROK_CLI_SCOPE} ok")
log(f"token ok expires_in={token.expires_in} refresh=yes")
return token
+2 -2
View File
@@ -20,10 +20,10 @@ CLIENT_ID = "b1a00492-073a-47ea-816f-4c329264a828"
ISSUER = "https://auth.x.ai"
DEVICE_CODE_URL = "https://auth.x.ai/oauth2/device/code"
TOKEN_URL = "https://auth.x.ai/oauth2/token"
# 对齐官方 0.2.101 discovery / docs(去掉二进制中已不出现的 grok-cli:access)
# cli-chat-proxy 要求 token scope 含 grok-cli:access(否则 grok-cli-token-auth-required)
SCOPE = (
"openid profile email offline_access "
"api:access conversations:read conversations:write"
"grok-cli:access api:access conversations:read conversations:write"
)
LogFn = Callable[[str], None]