关于 github-auth
用于配置 GitHub 身份验证,让 Agent 能处理仓库、拉取请求、议题和 CI。支持 `gh` CLI 与仅用 `git` 的配置,涵盖令牌、SSH 和无头环境。
主要功能
- 01检测可用的 GitHub 验证工具
- 02配置 HTTPS 令牌或 SSH 访问
- 03指导 `gh` CLI 登录流程
- 04通过 `curl` 访问 API
- 05排查常见验证问题
适用场景
- 01为 Agent 准备推送仓库更改的权限
- 02在无头主机上设置 GitHub 访问
- 03`gh` 不可用时选择验证备用方案
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nousresearch/ hermes-agent --skill github-auth安装后在 Claude Code 中输入/github-auth确认已加载。
附带文件scripts/gh-env.shscripts/git-credential-token.py
详细介绍
GitHub 身份验证设置
此技能用于设置身份验证,以便 Agent 能够使用 GitHub 仓库、PR、议题和 CI。包括两种方式:
git(始终可用) — 使用 HTTPS 个人访问令牌或 SSH 密钥ghCLI(如果已安装) — 通过更简单的身份验证流程,获得更丰富的 GitHub API 访问能力
检测流程
用户要求你使用 GitHub 时,首先运行此检查:
# Check what's available
git --version
gh --version 2>/dev/null || echo "gh not installed"
# Check if already authenticated
gh auth status 2>/dev/null || echo "gh not authenticated"
git config --global credential.helper 2>/dev/null || echo "no git credential helper"
决策树:
- 如果
gh auth status显示已通过身份验证 → 一切就绪,所有操作都使用gh - 如果已安装
gh,但尚未通过身份验证 → 使用下方的“gh auth”方式 - 如果未安装
gh→ 使用下方的“仅 git”方式(无需 sudo)
方法 1:仅使用 Git 进行身份验证(无需 gh,无需 sudo)
任何安装了 git 的机器都可以使用此方法。无需 root 权限。
选项 A:使用 HTTPS 和个人访问令牌(推荐)
这是兼容性最好的方法——适用于各种环境,无需配置 SSH。
步骤 1:创建个人访问令牌
告诉用户前往:https://github.com/settings/tokens
- 点击 “Generate new token (classic)”
- 设置一个名称,例如 “hermes-agent”
- 选择权限范围:
repo(完整的仓库访问权限,包括读取、写入、推送和 PR)workflow(触发和管理 GitHub Actions)read:org(如果需要使用组织仓库)
- 设置过期时间(建议默认设为 90 天)
- 复制令牌——之后将无法再次查看
步骤 2:配置 git 保存令牌
# Set up the credential helper to cache credentials
# "store" saves to ~/.git-credentials in plaintext (simple, persistent)
git config --global credential.helper store
# Now do a test operation that triggers auth — git will prompt for credentials
# Username: <their-github-username>
# Password: <paste the personal access token, NOT their GitHub password>
git ls-remote https://github.com/<their-username>/<any-repo>.git
输入一次凭据后,它们就会被保存,并用于后续所有操作。
替代方案:缓存辅助程序(凭据过期后会从内存中清除)
# Cache in memory for 8 hours (28800 seconds) instead of saving to disk
git config --global credential.helper 'cache --timeout=28800'
替代方案:将令牌直接设为远程 URL(按仓库配置)
# Embed token in the remote URL (avoids credential prompts entirely)
git remote set-url origin https://<username>:<token>@github.com/<owner>/<repo>.git
步骤 3:配置 git 身份信息
# Required for commits — set name and email
git config --global user.name "Their Name"
git config --global user.email "[email protected]"
步骤 4:验证
# Test push access (this should work without any prompts now)
git ls-remote https://github.com/<their-username>/<any-repo>.git
# Verify identity
git config --global user.name
git config --global user.email
选项 B:使用 SSH 密钥进行身份验证
适合偏好 SSH 或已配置密钥的用户。
步骤 1:检查是否已有 SSH 密钥
ls -la ~/.ssh/id_*.pub 2>/dev/null || echo "No SSH keys found"
步骤 2:如有需要,生成密钥
# Generate an ed25519 key (modern, secure, fast)
ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/id_ed25519 -N ""
# Display the public key for them to add to GitHub
cat ~/.ssh/id_ed25519.pub
告诉用户在此处添加公钥:https://github.com/settings/keys
- 点击 “New SSH key”
- 粘贴公钥内容
- 设置一个标题,例如 “hermes-agent-”
步骤 3:测试连接
ssh -T [email protected]
# Expected: "Hi <username>! You've successfully authenticated..."
步骤 4:配置 git 对 GitHub 使用 SSH
# Rewrite HTTPS GitHub URLs to SSH automatically
git config --global url."[email protected]:".insteadOf "https://github.com/"
步骤 5:配置 git 身份信息
git config --global user.name "Their Name"
git config --global user.email "[email protected]"
方法 2:使用 gh CLI 进行身份验证
如果已安装 gh,它可以一步完成 API 访问和 git 凭据配置。
通过交互式浏览器登录(桌面端)
注意事项(Windows 上由 Agent 驱动的会话): 通过 pty 后台进程运行
gh auth login时,应使用process(submit)回答提示,而不要使用仅包含\n的process(write)。在 Windows PTY(ConPTY/pywinpty)中,Enter 会被转换为回车符;单独的\n不会作为行终止符传递。因此,gh 的“Press Enter to open the browser”提示(会阻塞等待整行输入)会一直等待,导致登录卡住。另请注意,后台会话可能无法在用户的桌面上打开浏览器;如果用户反馈此问题,请改用下方的设备流程。
gh auth login
# Select: GitHub.com
# Select: HTTPS
# Authenticate via browser
手动 OAuth 设备流(无需 TTY — 已验证)
交互式登录不切实际时的备用方案(由 Agent 驱动的会话、无法启动浏览器、无头环境)。使用 gh 的公开 OAuth 客户端 ID;用户只需在 github.com/login/device 输入代码。范围:repo,read:org,gist 是 gh auth login --with-token 文档所述的最低要求;仅在需要推送工作流文件时才添加 ,workflow。
# 1. Request a device code (gh's official client_id)
RESP=$(curl -s -X POST -H "Accept: application/json" \
-d "client_id=178c6fc778ccc68e1d6a&scope=repo,read:org,gist" \
https://github.com/login/device/code)
DEVICE_CODE=$(echo "$RESP" | sed 's/.*"device_code":"\([^"]*\)".*/\1/')
USER_CODE=$(echo "$RESP" | sed 's/.*"user_code":"\([^"]*\)".*/\1/')
INTERVAL=$(echo "$RESP" | sed 's/.*"interval":\([0-9]*\).*/\1/'); INTERVAL=${INTERVAL:-5}
echo "Tell the user: go to https://github.com/login/device and enter code: $USER_CODE"
# 2. Poll for the token (respect interval; +5s on slow_down; ~15 min expiry).
# Run this loop as a background process and show the user the code first.
while true; do
sleep "$INTERVAL"
POLL=$(curl -s -X POST -H "Accept: application/json" \
-d "client_id=178c6fc778ccc68e1d6a&device_code=${DEVICE_CODE}&grant_type=urn:ietf:params:oauth:grant-type:device_code" \
https://github.com/login/oauth/access_token)
case "$POLL" in
*access_token*)
# Never echo the token; pipe it straight into gh.
# timeout guards the headless-keyring hang (see pitfall below) —
# on exit 124, fall back to writing ~/.config/gh/hosts.yml directly.
echo "$POLL" | sed 's/.*"access_token":"\([^"]*\)".*/\1/' | timeout 20 gh auth login --with-token \
|| { echo "WITH_TOKEN_HUNG_OR_FAILED — use the hosts.yml fallback below"; exit 1; }
gh auth setup-git
gh auth status
echo "LOGIN_COMPLETE"; break ;;
*authorization_pending*) ;; # keep polling
*slow_down*) INTERVAL=$((INTERVAL + 5)) ;; # back off per GitHub docs
*expired_token*) echo "CODE_EXPIRED — restart the flow"; exit 1 ;;
*access_denied*) echo "USER_DENIED"; exit 1 ;;
*) echo "UNEXPECTED: $POLL"; exit 1 ;;
esac
done
注意:在 Windows 上通过 winget 安装时,gh 位于 /c/Program Files/GitHub CLI — 在同一个 shell 中将其添加到 PATH:export PATH="$PATH:/c/Program Files/GitHub CLI"。
注意事项(无头 Linux):
gh auth login --with-token可能会无限期挂起。 在没有密钥环的无头设备上(VPS、容器、没有 dbus 会话),gh 的 凭据存储可能会因等待 secret-service 密钥环而无限期阻塞 — 即使使用--insecure-storage也会如此,且不会输出任何内容。如果命令在约 20 秒内 没有返回(可用timeout 20 …包装来检测),请跳过 gh 的登录机制,直接写入凭据存储:# $TOKEN = 上述设备流获得的访问令牌(切勿回显) mkdir -p ~/.config/gh LOGIN=$(curl -s -H "Authorization: token $TOKEN" https://api.github.com/user \ | sed 's/.*"login": *"\([^"]*\)".*/\1/') printf 'github.com:\n users:\n %s:\n oauth_token: %s\n git_protocol: https\n oauth_token: %s\n user: %s\n' \ "$LOGIN" "$TOKEN" "$TOKEN" "$LOGIN" > ~/.config/gh/hosts.yml chmod 600 ~/.config/gh/hosts.yml gh auth status # 直接读取 hosts.yml — 无需密钥环即可验证 gh auth setup-git # 配置 git 凭据助手(不会挂起)
gh auth status和setup-git会读取文件存储,不会访问密钥环, 因此可以立即使用。在无头 x86_64 VPS 上验证通过 (gh 2.97.0,2026 年 8 月),当时--with-token已两次挂起。
基于令牌的登录(无头环境/SSH 服务器)
echo "<THEIR_TOKEN>" | gh auth login --with-token
# Set up git credentials through gh
gh auth setup-git
如果 --with-token 在此处挂起,请使用上方注意事项中的 hosts.yml 备用方案。
验证
gh auth status
不使用 gh 调用 GitHub API
如果无法使用 gh,仍可通过 curl 搭配个人访问令牌调用完整的 GitHub API。其他 GitHub 技能就是这样实现备用方案的。
为 API 调用设置令牌
# Option 1: Export as env var (preferred — keeps it out of commands)
export GITHUB_TOKEN="<token>"
# Then use in curl calls:
curl -s -H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/user
从 Git 凭据中提取令牌
如果已配置 Git 凭据(通过 credential.helper store),可以提取令牌:
# Read from git credential store
uv run python "${HERMES_HOME:-$HOME/.hermes}/skills/github/github-auth/scripts/git-credential-token.py"
辅助方法:检测身份验证方式
在任何 GitHub 工作流开始时使用此模式:
# Try gh first, fall back to git + curl
if command -v gh &>/dev/null && gh auth status &>/dev/null; then
echo "AUTH_METHOD=gh"
elif [ -n "$GITHUB_TOKEN" ]; then
echo "AUTH_METHOD=curl"
elif _hermes_env="${HERMES_HOME:-$HOME/.hermes}/.env"; [ -f "$_hermes_env" ] && grep -q "^GITHUB_TOKEN=" "$_hermes_env"; then
export GITHUB_TOKEN=$(grep "^GITHUB_TOKEN=" "$_hermes_env" | head -1 | cut -d= -f2 | tr -d '\n\r')
echo "AUTH_METHOD=curl"
elif grep -q "github.com" ~/.git-credentials 2>/dev/null; then
export GITHUB_TOKEN=$(uv run python "${HERMES_HOME:-$HOME/.hermes}/skills/github/github-auth/scripts/git-credential-token.py")
echo "AUTH_METHOD=curl"
else
echo "AUTH_METHOD=none"
echo "Need to set up authentication first"
fi
故障排除
| 问题 | 解决方案 |
|---|---|
git push 要求输入密码 | GitHub 已禁用密码身份验证。请将个人访问令牌用作密码,或改用 SSH |
remote: Permission to X denied | 令牌可能缺少 repo 范围 — 请使用正确范围重新生成 |
fatal: Authentication failed | 缓存的凭据可能已过期 — 运行 git credential reject,然后重新进行身份验证 |
ssh: connect to host github.com port 22: Connection refused | 尝试通过 HTTPS 端口使用 SSH:在 ~/.ssh/config 中添加 Host github.com、Port 443 和 Hostname ssh.github.com |
| 凭据未持久保存 | 检查 git config --global credential.helper — 必须是 store 或 cache |
| 多个 GitHub 账户 | 在 ~/.ssh/config 中为每个主机别名使用不同的 SSH 密钥,或使用每个仓库单独的凭据 URL |
gh: command not found 且没有 sudo 权限 | 使用上方仅需 Git 的方法 1 — 无需安装 |