创建 GitHub Personal Access Token
摘要
- 本文写 GitHub 的两种 Personal Access Token:细粒度令牌(fine-grained)和经典令牌(classic)。每种先说它能访问什么,再写网页上怎么创建,以及在
git、gh和 REST API 里怎么用。gh命令按 2.102.0。 - HTTPS 凭据助手见 Git安装和常用命令(最新)。
gh auth login见 GitHub CLI 之 gh 命令。 - Managing your personal access tokens,GitHub’s token formats。
两种令牌
GitHub 从 2021 年 8 月起,HTTPS 的 git push、git pull 不再接受账号密码。调用 REST API 时,账号密码同样会被拒绝。令牌是专门发给这些场合的一串凭据:权限可以只开需要的那几项,泄漏后删掉这张令牌即可,不用改登录密码。
令牌代替账号密码,用来访问 GitHub API,以及走 HTTPS 的 git。它挂在创建它的用户身上,权限不会超过这个用户本人。账号失去某个仓库的权限后,对应令牌也跟着失效。
GitHub 建议能用细粒度令牌时就用细粒度令牌。代表组织做长期集成时,用 GitHub App,不必把个人令牌交给服务。
| 项目 | 细粒度令牌 | 经典令牌 |
|---|---|---|
| 设置页名称 | Fine-grained tokens | Tokens (classic) |
| 前缀 | github_pat_ |
ghp_ |
| 资源范围 | 一个资源所有者:你的用户,或一个组织 | 你的账号当时能访问的个人仓库,以及所在组织的仓库 |
| 权限 | 按仓库权限勾选,并可再限定到若干仓库 | 按 scope 勾选,例如 repo |
| 组织侧控制 | 组织可以要求管理员批准 | 组织可以禁用。禁用后访问该组织资源会得到 403 |
细粒度令牌还有这些边界:
-
一个令牌只能选一个资源所有者,不能同时覆盖多个组织。
-
对 GitHub 上全部公开仓库始终有只读,这项不随「只选几个仓库」关掉。
-
向自己未加入的公开仓库推送、以外部协作者身份访问组织仓库、访问 GitHub Packages、调用 Checks API、访问用户账号名下的 Projects,这些目前用经典令牌。
-
组织若禁止细粒度令牌,资源所有者列表里不会出现该组织。
经典令牌勾了 repo 之后,可以访问这个账号所能访问的每个仓库。不勾任何 scope 时,只能访问公开信息。连续一年没有使用过的经典令牌,GitHub 会删掉。
令牌和密码同等敏感。生成之后页面只显示一次原文,关掉就无法再查看。丢了就删掉重建。不要写进仓库,不要发到聊天记录。
创建前
-
账号邮箱要已经验证。未验证时生成会失败。
-
菜单名按 github.com 英文界面。入口都是右上角头像,然后 Settings,左侧 Developer settings。
-
日常推送可以走 SSH,或用 GitHub CLI 之 gh 命令 里的浏览器登录。令牌留给脚本、API 客户端,以及 HTTPS 远程在密码框里要填的凭据。GitHub Actions 里优先用工作流自带的
GITHUB_TOKEN。
创建细粒度令牌
打开 Fine-grained tokens,或从 Developer settings → Personal access tokens → Fine-grained tokens → Generate new token。账号最多保留 50 个细粒度令牌。还要更多时,改用 GitHub App。
-
Token name:给这张令牌起名,方便以后辨认用途。
-
Expiration:选择过期时间。页面允许不过期,但组织或企业如果设了最长寿命,不过期的选项会被拒绝。
-
Description:可选,写给自己看的用途说明。
-
Resource owner:选一个用户或一个组织。令牌只能访问这个所有者名下的资源。
-
资源所有者是组织、且该组织要求审批时,下面的框里填写申请理由。你自己是组织所有者时,申请会自动通过。其他人的令牌在批准前状态是
pending,只能读公开资源。 -
Repository access:只选需要的仓库。选 Only select repositories 后,在 Selected repositories 里勾选仓库。
-
Permissions:按资源所有者,页面会列出仓库权限、组织权限、账号权限。每项选需要的最低级别。
write包含read。
访问仓库时,GitHub 会自动加上 Metadata 的只读,这项不能单独去掉。常见仓库权限:
| 权限 | 级别 | 作用 |
|---|---|---|
| Contents | read | 克隆、拉取 |
| Contents | write | 推送。包含 read |
| Pull requests | read 或 write | 查看,或创建、合并 Pull Request |
| Issues | read 或 write | 查看,或创建 Issue |
| Actions | read | 查看 Actions 运行记录 |
| Workflows | write | 推送 .github/workflows 下的文件。这项只有 write |
推送工作流文件时,Contents 的 write 和 Workflows 的 write 都要有。完整权限表见 Permissions required for fine-grained personal access tokens。
点 Generate token。复制以 github_pat_ 开头的字符串,然后离开页面。
创建经典令牌
从 Developer settings → Personal access tokens → Tokens (classic) → Generate new token → Generate new token (classic)。直接打开的地址是 New personal access token (classic)。
-
Note:令牌名称。
-
Expiration:选页面上的预设天数,或 Custom 填日期。
-
Select scopes:勾选范围。从命令行访问私有仓库时勾
repo。
常用 scope:
| scope | 作用 |
|---|---|
repo |
私有仓库的代码、Issue、Pull Request |
workflow |
推送和修改 Actions 工作流文件。改 .github/workflows 时和 repo 一起勾 |
read:org |
读取组织、团队和成员 |
gist |
读写 Gist |
read:packages |
拉取 GitHub Packages |
write:packages |
发布 GitHub Packages |
delete_repo |
删除仓库 |
user |
读取和修改用户资料 |
全部 scope 见 Scopes for OAuth apps。
点 Generate token。复制以 ghp_ 开头的字符串。
使用
两种令牌的用法相同:HTTPS 的 git 把令牌填在密码框,API 放在 Authorization: Bearer 头里。gh 对两种令牌的存法不同,见下文。
组织启用了 SAML 单点登录时,创建后还要在令牌列表里对该组织点授权。未授权时,访问该组织资源会失败。步骤见 Authorizing a personal access token for use with SAML single sign-on。
HTTPS 的 git
远程必须是 https://github.com/...。地址是 git@github.com:... 时走 SSH 公钥,不会读取这张令牌。
1 | # Username 填 GitHub 用户名,Password 粘贴令牌 |
用户名要填。GitHub 用令牌完成认证。把账号密码填进 Password 会被拒绝。
第一次成功之后,令牌会按 credential.helper 写入钥匙串或凭据文件,之后新开的终端也会带上。助手怎么配,见 Git安装和常用命令(最新) 第 13 节。不要把令牌写进远程 URL,shell 历史和 .git/config 都会留下它。
git 不再提问就报 Authentication failed 时,凭据助手里多半还是旧密码。先改助手里 github.com 的密码,再重试。
gh
细粒度令牌用环境变量 GH_TOKEN。它只影响当前 shell,关掉终端就消失。gh auth login --with-token 会把令牌写进凭据库;细粒度令牌又限制在选定仓库上,之后访问其他仓库容易报权限错误。脚本里保持用 GH_TOKEN。
1 | # 只对当前 shell 生效 |
经典令牌可以从标准输入交给 gh,写入凭据库。这一步改的是凭据库,不只影响当前进程。gh auth login 要求的最小 scope 是 repo、read:org、gist。mytoken.txt 里只放令牌一行。
1 | gh auth login --with-token < mytoken.txt |
当前 shell 设置了 GH_TOKEN 时,gh 使用这个令牌,覆盖 gh auth login 已经保存的凭据。gh auth status 能通过,只说明凭据库里有账号。接着看环境里有没有 GH_TOKEN。
让 git 的 HTTPS 使用 gh 保存的凭据时,执行 gh auth setup-git。这一步改的是 Git 配置。细节见 GitHub CLI 之 gh 命令。
REST API
1 | # 200 且 JSON 里有 login,表示这张令牌被 API 接受 |
-
401:令牌字符串不对、已过期,或环境变量里是空的。 -
403:权限或 scope 不够;细粒度令牌还在pending;经典令牌被组织禁用,或 SAML 尚未授权。 -
设置页能看到令牌名称,只说明它还没被删除。这次调用是否成功,看上面这条
curl的状态码。
仓库权限可以用拉取远程引用来确认。细粒度令牌需要对目标仓库有 Contents 的 read,经典令牌需要 repo(私有仓库)或至少能访问该公开仓库。
1 | git ls-remote https://github.com/用户名/仓库名.git |
删除
不再使用时删掉。入口仍是 Developer settings → Personal access tokens,按类型进入 Fine-grained tokens 或 Tokens (classic),该令牌右侧点 Delete。
用某张令牌创建过的 deploy key,会随这张令牌一起被删除。