Skip to content

协作仓库使用 SSH 地址时,Docker 后端缺少 SSH 凭据导致轮询失败且提示不明确 #104

@keting

Description

@keting

请不要在这里报告安全问题。安全漏洞、敏感信息泄露、权限绕过或其他安全风险,请按照 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 分支附近版本

复现步骤

  1. 通过 Docker Compose 部署 HALF。

  2. 创建或编辑一个项目,将 HALF 协作仓库地址设置为 GitHub SSH 地址,例如:

    git@github.com:owner/repo.git
    

    该仓库可以是 public 或 private。

  3. 确保后端容器内没有可用 SSH key,例如 /root/.ssh/id_ed25519/root/.ssh/id_rsa 不存在。

  4. 进入该项目的 Plan 页面。

  5. 生成并复制 Prompt,使 Plan 进入轮询状态,或手动刷新规划状态。

  6. 查看 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.
Image

典型 Git 错误:

git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

建议改进

可以考虑以下一种或多种方式:

  1. 在项目创建/编辑页展示协作仓库 URL 的协议提示:

    • SSH 地址需要后端运行环境配置 SSH key。
    • HTTPS 地址访问 public 仓库通常不需要凭据。
    • private 仓库无论 SSH/HTTPS 都需要对应凭据。
  2. 在部署文档中增加“协作仓库访问凭据”说明:

    • Docker 部署时如何挂载 SSH key。
    • 如何配置 known_hosts
    • private 仓库和 public 仓库分别推荐使用什么 URL。
    • 主机可访问不代表容器可访问。
  3. 在后端 Git clone/fetch 失败时,根据错误类型返回更明确的错误:

    • Permission denied (publickey):提示 SSH key 缺失或权限不足。
    • Repository not found:提示仓库不存在或 private 仓库无权限。
    • 网络/DNS 错误:提示网络连接问题。
  4. 可选:对 GitHub public 仓库的 SSH 地址提供只读 HTTPS fallback。

    • 例如将 git@github.com:owner/repo.git 转换为 https://github.com/owner/repo.git 后尝试只读访问。
    • private 仓库仍需要凭据,fallback 不应掩盖权限问题。

验收标准

  • 文档或 UI 明确说明 SSH/HTTPS 协作仓库地址对凭据的要求。
  • Docker 部署文档说明如何让后端容器访问私有协作仓库。
  • 当 SSH clone/fetch 因 Permission denied (publickey) 失败时,页面或 API 错误能提示 SSH key 缺失或权限不足。
  • 用户可以区分 public 仓库使用 HTTPS 可匿名读取、SSH 地址仍需要 SSH key 这两种情况。

Metadata

Metadata

Assignees

Labels

area:backendBackend / Python / FastAPI relatedarea:ciCI, GitHub Actions, Docker/compose, and build toolingarea:docsDocumentation, guides, and contributor docsstatus:needs-triageNewly opened issue or PR awaiting maintainer triagetype:bugSomething isn't working

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions