Composer拉取私有仓库报“Permission denied (publickey)”的根本原因是Git调用SSH时未找到可用私钥或SSH agent未加载对应密钥;需检查ssh-add -l确认agent状态,确保SSH_AUTH_SOCK环境变量有效,并通过eval $(ssh-agent)和ssh-add加载密钥。

Composer拉取私有仓库时提示“Permission denied (publickey)”
这是最典型的症状:Composer执行 composer install 或 composer update 时卡在 Git 克隆阶段,报错类似 git@github.com: Permission denied (publickey) 或 fatal: Could not read from remote repository.。根本原因不是 Composer 本身问题,而是它调用系统 Git 时,Git 找不到可用的 SSH 私钥,或 SSH agent 没加载对应密钥。
确认当前 SSH agent 是否运行并已加载私钥
先别急着改配置,直接验证环境状态:
- 运行
ssh-add -l—— 若提示Could not open a connection to your authentication agent,说明 agent 没启动 - 若返回空(无输出),说明 agent 在运行但没加载任何密钥
- 若列出密钥路径(如
2048 SHA256:xxx /Users/you/.ssh/id_rsa (RSA)),说明已加载,但需确认该密钥是否对应目标仓库(比如 GitHub/GitLab 的部署密钥或个人密钥)
临时加载私钥:运行 ssh-add ~/.ssh/your_private_key(把 your_private_key 换成你实际的私钥文件名)。注意:如果私钥有密码,此时会要求输入;若不想每次输密码,可加 -K(macOS)或用 keychain(Linux)持久化,但不建议在共享环境这么做。
让 Composer 始终走 SSH agent 而非直读磁盘私钥
Composer 默认信任 Git 的行为,而 Git 默认尝试用 ssh-agent,但很多终端会话(尤其是 IDE 内置终端、CI 环境、远程 SSH 登录后)并不自动继承 agent 连接。关键点在于环境变量 SSH_AUTH_SOCK:
- 检查是否设置:
echo $SSH_AUTH_SOCK—— 应输出类似/private/tmp/com.apple.launchd.xxx/Listeners(macOS)或/tmp/ssh-xxx/agent.xxxx(Linux) - 若为空,说明当前 shell 未接入 agent。解决方法不是改 Composer 配置,而是重连 agent:
eval $(ssh-agent),再ssh-add ~/.ssh/id_rsa - ⚠️ 不要手动设置
git config core.sshCommand指向带-i参数的 ssh(如ssh -i ~/.ssh/id_rsa)—— 这会让私钥路径硬编码进 Git 配置,丧失 agent 的密码管理、多密钥自动路由能力,且不安全
CI/CD 或 Docker 环境下 SSH agent 加载失败的典型表现
在 GitHub Actions、GitLab CI 或本地 docker run 中,ssh-agent 默认不运行,且 SSH_AUTH_SOCK 根本不存在。这时候光靠 ssh-add 没用,因为没 agent 可加。
- GitHub Actions 推荐用官方
webfactory/ssh-agentaction,它自动启动 agent 并注入环境变量 - GitLab CI 可用
ssh-agentjob before_script:eval $(ssh-agent -s)+ssh-add (注意 <code>$SSH_PRIVATE_KEY是预设的 CI 变量,且需 base64 解码或直接存为文件) - Docker 容器内:除非显式挂载
SSH_AUTH_SOCK和 socket 文件(不推荐),否则应改用 deploy token 或 HTTPS + personal access token(配合composer config http-basic)替代 SSH
私钥永远不该出现在 composer.json、Git 提交历史或容器镜像层里。agent 方式只传递 socket 句柄,是目前最平衡安全与便利的做法。











