README
¶
authconv-go
OpenAI / Grok OAuth 凭证格式转换库与命令行工具,Go 实现。
把 ChatGPT /api/auth/session、Codex auth.json、xAI OIDC、Grok CLI auth.json、CPA、sub2api 或散装 token JSON 归一化后,渲染成目标工具所需格式。
- 纯本地 — 转换、解析、验真全部离线完成,运行时不发起任何网络请求,不上传凭据
- 自动识别 — 按内容识别输入格式与账号平台,不依赖文件扩展名
- 默认验真 — 用内置的 OpenAI / xAI 公钥离线验证 access token 签名,可显式关闭
- 可作库调用 — 一个函数完成转换,也可以逐层拆开控制
- 零依赖 — 只用 Go 标准库
安装
作为库:
go get github.com/yangbin1322/authconv-go
作为命令行工具:
go install github.com/yangbin1322/authconv-go/cmd/authconv@latest
需要 Go 1.26 或更新版本。
作为库使用
最简用法
package main
import (
"fmt"
"os"
"github.com/yangbin1322/authconv-go/authconv"
)
func main() {
data, _ := os.ReadFile("creds.json")
result, err := authconv.ConvertBytes(data, "creds.json", authconv.ConvertOptions{
Formats: []authconv.OutputFormat{authconv.FormatCPA},
})
if err != nil {
panic(err)
}
for _, file := range result.Files {
fmt.Println("==", file.Path)
fmt.Println(file.Content)
}
}
输入按内容识别,支持 JSON、JSONL、连续拼接的多个 JSON 文档以及 ZIP。
不指定格式则自动选择
不传 Formats 时,按账号平台选出全部适用格式——OpenAI 账号不会产出 Grok 格式,反之亦然:
result, _ := authconv.ConvertBytes(data, "creds.json", authconv.ConvertOptions{})
// xAI 账号 → cpa / sub2api / grok / grok2api
// OpenAI 账号 → cpa / sub2api / codex2api / codexmanager / codex
转换文件或目录
// 目录会递归读取全部普通文件
result, err := authconv.ConvertFiles([]string{"accounts/", "extra.json"}, authconv.ConvertOptions{
Formats: []authconv.OutputFormat{authconv.FormatSub2API},
})
只读取账号信息
不需要输出文件、只想看账号内容时:
accounts, diagnostics := authconv.ParseAccounts(data, "creds.json", authconv.ConvertOptions{})
for _, account := range accounts {
fmt.Println(account.Provider, account.Email, account.ExpiresAt)
if account.TokenVerification != nil {
fmt.Println(" 验真:", account.TokenVerification.Status)
}
}
单独验证一个 token
result := authconv.VerifyAccessToken(token, authconv.ProviderOpenAI)
if result.Verified() {
fmt.Println("签名真实")
} else {
fmt.Println("未通过:", result.Verification.Reason)
}
ConvertOptions
| 字段 | 说明 |
|---|---|
Formats |
输出格式;为空则按 provider 自动选择 |
OutputModes |
覆盖 sub2api / codex2api 的 merged | single |
TextMode |
设为 TextModeJSONL 时每账号一行 |
SkipVerification |
跳过离线验真,按字段直接搬运 |
ExcludeRefreshToken |
输出不含 refresh_token |
ExcludeSyntheticIDToken |
输出不含自动合成的 id_token |
Now |
固定渲染时间戳,便于测试复现 |
InputFormat |
强制按指定格式解析,而非自动识别 |
零值即推荐默认:开启验真、包含 refresh_token 与合成 id_token。
备注字段
各工具的备注字段名不同,转换时会自动互相搬运:
| 格式 | 字段 |
|---|---|
| sub2api | accounts[].notes |
| CPA | 顶层 note |
// 输入 sub2api: {"accounts":[{"notes":"我的备注", ...}]}
// 输出 CPA: {"type":"xai", ..., "note":"我的备注"}
反向同样成立,往返不丢内容。账号合并时也会补齐备注。
没有备注的账号不会产生空字段——不会凭空多出 "note": ""。
grok 与 grok2api 不带备注:它们是 Grok CLI / Grok2API 的官方 auth 结构,
字段集固定,塞入自定义字段可能被下游工具拒绝。
关于验真
默认只输出通过离线验真的账号。被拒账号不会出现在 Files 里,但会计入 RejectedCount 与 RejectionReasons:
result, _ := authconv.ConvertBytes(data, "creds.json", authconv.ConvertOptions{})
if len(result.Files) == 0 && result.RejectedCount > 0 {
for reason, count := range result.RejectionReasons {
fmt.Printf("%d 个账号被拒: %s\n", count, reason)
}
}
验真只判断签名是否真实,不判断 token 是否已撤销或账号当前是否可用;签名真实但已过期的凭证仍可转换。
SkipVerification: true 会让伪造凭证也被正常导出,只在明确知道输入可信时使用。
更细的控制
高层 API 之下的各层都是导出的,需要时可以自己组装:
store := authconv.NewAccountStore()
ingestion := authconv.IngestSources(sources, store, authconv.IngestionOptions{
VerifyTokens: true,
})
manifest, _ := authconv.BuildExportManifest(store, authconv.ExportRequest{
Formats: []authconv.OutputFormat{authconv.FormatCPA},
})
for _, entry := range manifest.Entries {
content, _ := authconv.RenderEntry(store, entry, authconv.RenderOptions{})
_ = content
}
完整 API 见 pkg.go.dev。
作为命令行使用
# 默认转换,输出到 ./output
authconv creds.json
# 指定格式
authconv creds.json -f cpa -o out/
# 一次输出所有适用格式
authconv creds.json -f all -o out/
# 递归读取目录
authconv accounts/ -f all -o out/
# 输出到 stdout,方便接 jq
authconv creds.json -f sub2api --stdout | jq .
# 只看解析结果,不写文件
authconv creds.json --inspect
# 预览会写哪些文件
authconv creds.json -f all --dry-run
# 跳过验真,按字段直接转换
authconv creds.json -f cpa --no-verify-token
支持的输出格式:
| 格式 | 目标 |
|---|---|
cpa |
CLIProxyAPI |
sub2api |
sub2api |
codex2api |
codex2api |
codexmanager |
Codex-Manager |
codex |
Codex CLI auth.json |
grok |
Grok CLI auth.json |
grok2api |
Grok2API 多账号池 |
完整 CLI 参考见 docs/cli.md。
退出码:0 成功;1 有账号被拒或存在输入诊断;2 参数错误;3 文件系统错误。
规则文档
开发
go test ./... # 运行测试
go build -o bin/authconv ./cmd/authconv # 构建 CLI
构建时要带 -o 且输出到别的目录:默认输出名 authconv 会和仓库里的
authconv/ 源码包目录同名,go build 会把产物写进那个目录而不报错。
测试直接比对 testdata/fixtures/expected/ 下的既有 fixture,覆盖 7 种输出格式的字段内容与字段顺序——顺序是对下游工具的契约,不能随意改动。
致谢
移植自 authconv(TypeScript)。感谢 Linux.do 社区的讨论与反馈。
License
MIT