使用GitHub Action的GITHUB_TOKEN调用GitHub API始终返回Bad credentials
问题:GitHub Action的GITHUB_TOKEN调用API返回"Bad credentials"
我尝试验证请求是否来自GitHub Action,因此创建了如下Workflow:
name: test on: # workflow_dispatch: push: permissions: read-all jobs: build: runs-on: ubuntu-latest steps: - name: test token run: | curl "http://xxxxx/test_token?github_token=${{ secrets.GITHUB_TOKEN }}"
服务器打印出的GitHub Token如下:token is: ghs_xxxxxx482tJb
随后我使用该Token通过curl调用GitHub API,但始终返回Bad credentials错误。我尝试调用的API包括:
https://api.github.com/repos/my_org/repo_name/pageshttps://api.github.com/repos/my_org/repo_name/actions/workflowshttps://api.github.com/installation/repositories
请求示例:
$> curl -L \ -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer ghs_xxxxxsOUCk482tJb"\ -H "X-GitHub-Api-Version: 2022-11-28" \ https://api.github.com/repos/ky-infrastructure/tool-script/actions/workflows
响应结果:
{ "message": "Bad credentials", "documentation_url": "https://docs.github.com/rest" }
原因分析及解决方案
1. GITHUB_TOKEN的时效性限制
GITHUB_TOKEN是GitHub自动生成的临时令牌,有效期仅60分钟,且Workflow执行结束后会立即失效。你拿到的token大概率已经过期,导致API调用失败。
2. 令牌权限与类型不匹配
https://api.github.com/installation/repositories属于GitHub App安装相关API,需要的是GitHub App安装令牌,而GITHUB_TOKEN是仓库级临时令牌,根本无法调用这类接口。- 前两个仓库相关API,即使权限配置正确(你设置的
read-all已覆盖只读权限),只要token过期,同样会返回凭证错误。
3. 验证GitHub Action请求的正确姿势
不要通过传递GITHUB_TOKEN来验证请求来源,这种方式既不安全(token易泄露)也不可靠(过期快)。正确做法是用GitHub的Webhook签名验证:GitHub发送请求时会带上X-Hub-Signature-256头,你用仓库设置的Webhook密钥对请求体做哈希运算,和签名头对比即可验证请求合法性。
4. 正确调用API的方式
- 若在Workflow内部调用API:直接在步骤中使用
${{ secrets.GITHUB_TOKEN }},确保permissions配置了所需权限(read-all已满足大部分只读场景),无需将token传到外部服务器。 - 若必须在外部服务器调用API:不要用GITHUB_TOKEN,创建个人访问令牌(PAT),赋予对应仓库/组织权限,将PAT存到仓库secrets中,在Workflow里传递这个PAT到服务器使用。
- 若需调用installation相关API:必须创建GitHub App并安装到目标组织,生成安装令牌后才能调用,GITHUB_TOKEN无法替代。
内容的提问来源于stack exchange,提问作者afraid.jpg
相关产品推荐
相关产品推荐

