mcpField
G
github-auth

github-auth

github.com/nousresearch开发258.1k306 次安装今天更新
代码仓库

关于 github-auth

用于配置 GitHub 身份验证,让 Agent 能处理仓库、拉取请求、议题和 CI。支持 `gh` CLI 与仅用 `git` 的配置,涵盖令牌、SSH 和无头环境。

主要功能

  1. 01检测可用的 GitHub 验证工具
  2. 02配置 HTTPS 令牌或 SSH 访问
  3. 03指导 `gh` CLI 登录流程
  4. 04通过 `curl` 访问 API
  5. 05排查常见验证问题

适用场景

  1. 01为 Agent 准备推送仓库更改的权限
  2. 02在无头主机上设置 GitHub 访问
  3. 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 密钥
  • gh CLI(如果已安装) — 通过更简单的身份验证流程,获得更丰富的 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"

决策树:

  1. 如果 gh auth status 显示已通过身份验证 → 一切就绪,所有操作都使用 gh
  2. 如果已安装 gh,但尚未通过身份验证 → 使用下方的“gh auth”方式
  3. 如果未安装 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 — 无需安装

评论

支持 Markdown