请不要在这里报告安全问题。安全漏洞、敏感信息泄露、权限绕过或其他安全风险,请按照 SECURITY.zh-CN.md 私下报告。
摘要
HALF 设计上允许使用私有仓库或公有仓库作为协作仓库。但当协作仓库配置为 GitHub SSH 地址,并且 Docker 后端容器内没有可用 SSH key 时,后端轮询会因为 Permission denied (publickey) 失败。当前页面错误提示较泛化,用户不容易判断是 SSH 凭据缺失、仓库权限不足、仓库不存在,还是应该改用 HTTPS 地址。
环境
- 部署方式:docker compose
- OS: macOS / Linux 均可能复现
- Docker / Docker Compose 版本:未限定
- 浏览器或客户端:任意浏览器
- Commit 或版本:当前 main 分支附近版本
复现步骤
-
通过 Docker Compose 部署 HALF。
-
创建或编辑一个项目,将 HALF 协作仓库地址设置为 GitHub SSH 地址,例如:
git@github.com:owner/repo.git
该仓库可以是 public 或 private。
-
确保后端容器内没有可用 SSH key,例如 /root/.ssh/id_ed25519 或 /root/.ssh/id_rsa 不存在。
-
进入该项目的 Plan 页面。
-
生成并复制 Prompt,使 Plan 进入轮询状态,或手动刷新规划状态。
-
查看 Plan 状态区域和后端日志。
期望行为
HALF 继续支持私有仓库和公有仓库作为协作仓库,同时用户应能清楚知道不同 URL 协议对凭据的要求:
- SSH 地址:后端运行环境必须配置 SSH key,并且 key 需要具备目标仓库权限。
- HTTPS 地址:public 仓库通常可以匿名只读访问;private 仓库需要 token 或其他凭据。
- Docker 部署时,主机可以访问仓库不代表后端容器可以访问仓库,需要显式向容器提供凭据。
当轮询失败时,错误提示应尽量明确指出是仓库地址错误、仓库不存在、权限不足、SSH key 缺失,还是网络问题。
实际行为
Plan 状态区域显示较泛化的错误,例如:
无法访问 Git 仓库。请检查仓库是否存在、仓库地址是否正确,是否有访问该仓库的权限。HALF 会自动重试。
后端日志中可见类似:
Git sync failed while polling project <id>: git clone failed: Command '['git', 'clone', 'git@github.com:owner/repo.git', '/app/repos/<id>']' returned non-zero exit status 128.
在后端容器中手动执行类似命令:
git clone git@github.com:owner/repo.git /tmp/half-git-test
可能得到:
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
GitHub SSH 地址 git@github.com:owner/repo.git 通过 SSH 协议访问。即使仓库是 public,只要使用 SSH 地址,仍然需要后端运行环境具备可用 SSH 认证环境。因此 Docker 后端容器没有 SSH key 时会失败。
日志或截图
典型日志:
Git sync failed while polling project <id>: git clone failed: Command '['git', 'clone', 'git@github.com:owner/repo.git', '/app/repos/<id>']' returned non-zero exit status 128.
典型 Git 错误:
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
建议改进
可以考虑以下一种或多种方式:
-
在项目创建/编辑页展示协作仓库 URL 的协议提示:
- SSH 地址需要后端运行环境配置 SSH key。
- HTTPS 地址访问 public 仓库通常不需要凭据。
- private 仓库无论 SSH/HTTPS 都需要对应凭据。
-
在部署文档中增加“协作仓库访问凭据”说明:
- Docker 部署时如何挂载 SSH key。
- 如何配置
known_hosts。
- private 仓库和 public 仓库分别推荐使用什么 URL。
- 主机可访问不代表容器可访问。
-
在后端 Git clone/fetch 失败时,根据错误类型返回更明确的错误:
Permission denied (publickey):提示 SSH key 缺失或权限不足。
Repository not found:提示仓库不存在或 private 仓库无权限。
- 网络/DNS 错误:提示网络连接问题。
-
可选:对 GitHub public 仓库的 SSH 地址提供只读 HTTPS fallback。
- 例如将
git@github.com:owner/repo.git 转换为 https://github.com/owner/repo.git 后尝试只读访问。
- private 仓库仍需要凭据,fallback 不应掩盖权限问题。
验收标准
请不要在这里报告安全问题。安全漏洞、敏感信息泄露、权限绕过或其他安全风险,请按照
SECURITY.zh-CN.md私下报告。摘要
HALF 设计上允许使用私有仓库或公有仓库作为协作仓库。但当协作仓库配置为 GitHub SSH 地址,并且 Docker 后端容器内没有可用 SSH key 时,后端轮询会因为
Permission denied (publickey)失败。当前页面错误提示较泛化,用户不容易判断是 SSH 凭据缺失、仓库权限不足、仓库不存在,还是应该改用 HTTPS 地址。环境
复现步骤
通过 Docker Compose 部署 HALF。
创建或编辑一个项目,将 HALF 协作仓库地址设置为 GitHub SSH 地址,例如:
该仓库可以是 public 或 private。
确保后端容器内没有可用 SSH key,例如
/root/.ssh/id_ed25519或/root/.ssh/id_rsa不存在。进入该项目的 Plan 页面。
生成并复制 Prompt,使 Plan 进入轮询状态,或手动刷新规划状态。
查看 Plan 状态区域和后端日志。
期望行为
HALF 继续支持私有仓库和公有仓库作为协作仓库,同时用户应能清楚知道不同 URL 协议对凭据的要求:
当轮询失败时,错误提示应尽量明确指出是仓库地址错误、仓库不存在、权限不足、SSH key 缺失,还是网络问题。
实际行为
Plan 状态区域显示较泛化的错误,例如:
后端日志中可见类似:
在后端容器中手动执行类似命令:
可能得到:
GitHub SSH 地址
git@github.com:owner/repo.git通过 SSH 协议访问。即使仓库是 public,只要使用 SSH 地址,仍然需要后端运行环境具备可用 SSH 认证环境。因此 Docker 后端容器没有 SSH key 时会失败。日志或截图
典型日志:
典型 Git 错误:
建议改进
可以考虑以下一种或多种方式:
在项目创建/编辑页展示协作仓库 URL 的协议提示:
在部署文档中增加“协作仓库访问凭据”说明:
known_hosts。在后端 Git clone/fetch 失败时,根据错误类型返回更明确的错误:
Permission denied (publickey):提示 SSH key 缺失或权限不足。Repository not found:提示仓库不存在或 private 仓库无权限。可选:对 GitHub public 仓库的 SSH 地址提供只读 HTTPS fallback。
git@github.com:owner/repo.git转换为https://github.com/owner/repo.git后尝试只读访问。验收标准
Permission denied (publickey)失败时,页面或 API 错误能提示 SSH key 缺失或权限不足。