ghtkn - 用 GitHub App 短期 token 替代本地长期 PAT
本地开发里最容易被低估的风险之一,是 GitHub token 的生命周期。很多人为了让 gh、脚本、私有仓库 clone 或自动化命令跑得顺手,会在机器上长期放一个 PAT,或者依赖 GitHub CLI 的 OAuth token。它们用起来方便,但一旦被日志、shell history、dotfiles、备份或恶意扩展带走,影响范围和持续时间都不小。
今天推荐的 suzuki-shunsuke/ghtkn 就是针对这个问题的小工具。它是一个 Go 写的 CLI,通过 GitHub App 的 Device Flow 生成 8 小时有效期的 User Access Token,并把 token 存到本机后端里。默认后端是 OS keyring,也可以在容器、microVM 等没有 keyring 的环境里切换到 text 或 agent backend。
发布时 GitHub 页面显示项目约 178 stars、1 fork,主要语言是 Go,许可为 MIT。Release 页面把 v0.2.4 标为 latest stable release,同时可以看到 v0.2.5 系列 pre-release;仓库当前 USAGE.md 生成的帮助文本显示版本为 0.2.5。
项目概览
| 属性 | 详情 |
|---|---|
| 仓库 | suzuki-shunsuke/ghtkn |
| 定位 | 用 GitHub App User Access Token 做本地 GitHub 认证的 CLI |
| Stars | 约 178 |
| Forks | 1 |
| 主要语言 | Go |
| 许可 | MIT |
| Latest stable release | v0.2.4 |
它解决的是本地长期 token 习惯
ghtkn 的目标不是做一个新的 GitHub 客户端,而是把“本地命令如何拿到 GitHub token”这件事做得更短期、更可控。
它使用的是 GitHub App User Access Token,而不是传统 PAT。用户先创建一个启用 Device Flow 的 GitHub App,把 Client ID 写进 ghtkn.yaml,然后运行:
ghtkn get
第一次运行时,工具会引导用户去 GitHub device login 页面授权。授权完成后,ghtkn 输出一个以 ghu_ 开头的 user access token。README 里强调这个 token 的有效期是 8 小时;如果后续调用时缓存的 token 仍有效,工具会复用它,否则重新走授权流程。
这个模型的关键点是:Client ID 不是 secret,不需要在本机保存 GitHub App private key 或 client secret。token 的权限也同时受 GitHub App 权限和用户自身权限约束。也就是说,App 没有的权限不会凭空出现,用户不能访问的仓库也不会因为 token 变成可访问。
可以包住 gh 和 Git credential helper
README 给出的最直接用法,是把 ghtkn get 包进 GitHub CLI:
env GH_TOKEN=$(ghtkn get) gh issue create -R owner/repo --title "Hello" --body "Created by ghtkn"
实际使用时,你可以写一个 shell wrapper,让 gh 每次在没有 GH_TOKEN / GITHUB_TOKEN 时自动调用 ghtkn get。这样日常命令仍然是 gh pr view、gh issue create、gh api,但 token 来源换成了短期 GitHub App user token。
另一个重要能力是 Git Credential Helper。ghtkn >= v0.1.2 可以通过:
git config --global credential.helper '!ghtkn git-credential'
接入 Git 的 HTTPS credential 流程。文档还提醒,如果系统里已经配置了其他 helper,需要用空的 helper = 重置 helper 列表,避免 Git 仍然优先调用 macOS keychain 等旧 helper。
这类细节很实际。很多 token 泄露不是来自工具本身,而是来自“我以为当前命令用的是新配置,实际上系统还在用旧 credential helper”。ghtkn 把这部分故障排查写进文档,对团队落地会有帮助。
多个 GitHub App 可以按目录切换
ghtkn.yaml 支持配置多个 app,并可以通过命令参数或 GHTKN_APP 选择使用哪一个。README 里举了用 direnv 按目录切换 app 的例子:进入某个组织的仓库目录后,.envrc 只设置 app 名称,而不是写入 token。
这适合需要区分权限边界的人。比如个人仓库使用一个无权限或低权限 app,公司组织使用只装到特定仓库的 app,开源维护使用另一个 app。对用户来说,命令还是 ghtkn get 或被包装后的 gh;对安全边界来说,每个 app 的安装范围和权限可以单独控制。
它也适合默认低权限策略。README 里提到,一个没有额外 permissions 的 app 仍然可以用于读取 public repository,并帮助避免未认证 API rate limit。需要写 issue、PR、contents 或 statuses 时,再给对应 app 增加权限并安装到目标仓库。
后端选择覆盖桌面、容器和 microVM
默认情况下,ghtkn 把 token 存进 OS keyring:Windows Credential Manager、macOS Keychain 或 GNOME Keyring。对普通桌面开发环境,这是最自然的选择。
但现在很多本地开发流也会发生在容器、devcontainer、microVM 或远程 shell 里,这些环境经常没有可用的 keyring。ghtkn 为这种情况提供了 GHTKN_BACKEND:
keyring:默认后端,使用系统 keyring。text:把 token 存成权限为0600的明文文件。agent:通过本地 agent 用 AES-256-GCM 加密缓存 token。
text 后端胜在简单,但文档明确建议不要把目录放进 git 或云同步,并启用磁盘加密。agent 后端更适合没有 OS keyring 但仍然希望加密缓存的环境,只是需要启动 agent、解锁 passphrase,并管理 socket、key 和 token 目录。
这部分设计让 ghtkn 不只是“桌面上替代 PAT”。如果你在 devcontainer 里跑 CLI agent,或者用 microVM 做隔离开发,仍然可以通过 agent backend 避免把 GitHub token 长期暴露成环境变量。
对 agent 工作流尤其有意义
我觉得 ghtkn 对现在的 AI 编码工作流很有现实意义。编码代理经常需要调用 gh 查看 issue、PR、CI 状态,或者通过 HTTPS clone / fetch 仓库。最省事的做法是给它一个长期 token,但这也是最容易把权限边界做坏的做法。
ghtkn 提供了一个更窄的入口:token 短期有效,来自 GitHub App,权限受 app 和用户共同约束,默认存进本机安全后端。代理命令可以通过 wrapper 临时拿 token,而不是把 token 写进环境、配置文件或 prompt。
当然,它不是自动化万能解。Device Flow 是交互式的,不适合无人值守 CI。README 也写明,GHTKN_ENABLE_DEVICE_FLOW=false 可以让后台进程在需要交互时快速失败,避免代理或终端后台进程卡住等待一次看不见的授权。
这点反而是清晰边界:本地开发可以交互授权,CI 应该使用更适合 CI 的 GitHub App installation token、OIDC 或专门的 secret 管理方案。不要把一个本地工具硬塞进所有环境。
使用前要确认限制
GitHub App User Access Token 并不能覆盖所有 GitHub API 场景。README 的 limitations 提到,Packages API 仍然需要 classic PAT;对其他用户仓库做写操作也会受 GitHub App 安装范围限制。如果目标仓库没有安装对应 App,创建 PR 这类操作可能不适合直接走 ghtkn token。
这也是它与 PAT 的本质区别。PAT 往往是“给一个 token 很多能力”,ghtkn 更像是“让每个能力都回到 GitHub App 安装和权限模型里”。这会带来一些配置成本,但换来的是更可解释的失败和更小的泄露半径。
如果团队要推广,建议先从只读或低风险场景开始:读取 issue、调用 gh api 查状态、访问 public repo、为个人仓库测试 Git credential helper。等流程稳定后,再为需要写操作的仓库配置更明确的 App 权限。
小结
suzuki-shunsuke/ghtkn 是一个很窄但很有工程价值的安全工具:用 GitHub App Device Flow 生成 8 小时 User Access Token,把 token 存进本机后端,然后让 gh、Git credential helper 或脚本按需取用。
它不会消除所有 GitHub 认证问题,也不适合替代 CI 里的正式 secret 管理。但如果你的本地机器、devcontainer 或 agent 工作台还依赖长期 PAT,ghtkn 值得试一试。它把“方便地访问 GitHub”和“长期持有高风险 token”拆开了:本地命令仍然顺手,权限和有效期则更接近最小暴露原则。