feat(chv): 对齐 Muse P3 收尾——authd 替身凭证 + Sentinel 出口审批

- 新测试 cloud/tests/test_chv_muse_p3.py 30 项:替身过期、真 token
  泄露面、SSRF 挡截、deny/ask 路径、authd-seed 拆分、wake 预审、
  客内 authd 守护进程、git credential helper 端到端(真 git fill)
- 8 个旧测试按新 authd 行为改写(未删测试、未放宽断言):
  GITEA_TOKEN 改走 authd-seed,build_ssh_command 不再 source 进
  codex 环境;wake 测试补 Sentinel 白名单 + 假解析器
- 7 处超 50 行函数拆到 50 行内(不改行为);补 authd/sentinel
  公共 API 注解,mypy 在改动文件上干净
- 真问题修复:git 默认不把 path 发给 helper,chv-sync boot 加
  credential.useHttpPath=true,否则 authd 路径每次都拒绝
- 全量 cloud 套件 1897 项 OK(skipped=8)

真机待验证(未做,等第三棒让出 WSL 测试机):见
docs/chv-muse-p3-gap.md §3.6 清单
This commit is contained in:
host committed 2026-11-06 21:21:55 +00:00
1 parent 06c3e172fe
commit a90cf78d84
15 files changed
+2370 -93

No files matched your search

+36 -19
View File
@@ -7,19 +7,18 @@
# 的规则:分叉或冲突时失败关闭,不强制覆盖、不自动 rebase、
# 不静默丢提交。
#
# 凭证绝不进镜像。启动时由 seed 盘投递 /etc/chv/guest-env
# (0600,root 所有),格式(KEY=VALUE,每行一项):
# GITEA_URL=https://gitea.tose.top
# GITEA_USER=<Gitea 用户名>
# GITEA_TOKEN=<专用 API token,仅此次测试/此次 VM 有效>
# SYNC_REPO=<owner/repo>
# SYNC_BRANCH=<可选,默认分支>
# GITEA_EMAIL=<可选,commit 身份邮箱;不给则留镜像占位>
# boot(root,cloud-init runcmd 调)读 guest-env,把 token 写进
# 凭证绝不进镜像。启动时由 seed 盘投递两份文件(0600,root 所有):
# /etc/chv/guest-env(非密钥同步变量:GITEA_URL/GITEA_USER/
# SYNC_REPO/SYNC_BRANCH/GITEA_EMAIL)与
# /etc/chv/authd-seed(feat-chv-muse-p3:只装 GITEA_TOKEN,
# 只给客内 authd 守护进程读)。
# boot(root,cloud-init runcmd 调)读 guest-env,authd 在时配
# git credential helper 走 authd 按次取凭证(只进 git 子进程
# 内存,不落盘);authd 不在时(旧镜像)才回落到把 token 写进
# /home/chv/.git-credentials(0600,chv 所有,git credential
# store 标准机制),再以 chv 身份 clone 到 ~/workspace/<仓名>。
# pull/push/status 以 chv 身份跑,只用已落盘的 credential,不
# 再读 guest-env;token 不会出现在 git remote URL 或镜像里。
# store 标准机制)并警告。pull/push/status 以 chv 身份跑,用
# helper 或已落盘的 credential,不再读 guest-env;token 不会
# 出现在 git remote URL 或镜像里。
#
# 用法:
# chv-sync boot # 启动时 clone(已 clone 则静默退出,不自动 pull)
@@ -64,7 +63,6 @@ cmd_boot() {
set -a; . "$GUEST_ENV"; set +a
: "${GITEA_URL:?guest-env 缺 GITEA_URL}"
: "${GITEA_USER:?guest-env 缺 GITEA_USER}"
: "${GITEA_TOKEN:?guest-env 缺 GITEA_TOKEN}"
: "${SYNC_REPO:?guest-env 缺 SYNC_REPO}"
[ "$(id -u)" = "0" ] || die "boot 须以 root 运行(cloud-init runcmd)"
local host="${GITEA_URL#https://}"
@@ -74,12 +72,31 @@ cmd_boot() {
local dir="$WORKSPACE/$name"
mkdir -p "$WORKSPACE"
chown "$SYNC_USER:$SYNC_USER" "$WORKSPACE"
# token 只落盘进用户家目录的 credential store(0600),
# 不进 git remote URL、不进镜像、不进日志(此处不打印 token)。
local creds="$USER_HOME/.git-credentials"
printf 'https://%s:%s@%s\n' "$GITEA_USER" "$GITEA_TOKEN" "$host" > "$creds"
chmod 0600 "$creds"
chown "$SYNC_USER:$SYNC_USER" "$creds"
# feat-chv-muse-p3:authd 路径——socket 存在时凭证走 helper,
# 不再把真 token 写进 .git-credentials 落盘;helper 按次向
# authd 取凭证,只进 git 子进程内存。socket 不存在(旧镜像)
# 时走旧路径 + 警告(过渡兼容,旧镜像退役后改为 fail-closed)。
# 注意:authd 路径下 GITEA_TOKEN 不在 guest-env 里(它只进
# authd-seed 给守护进程),所以这里不要求它;旧路径才要求。
local authd_socket="${CHV_AUTHD_SOCKET:-/run/chv-authd/authd.sock}"
local helper="/usr/local/bin/git-credential-chv-authd"
if [ -S "$authd_socket" ] && [ -x "$helper" ]; then
runuser -u "$SYNC_USER" -- env HOME="$USER_HOME" git config --global credential.helper "$helper"
# helper 按路径推断仓库与操作(Sentinel L7 绑定),git
# 默认不把 path 发给 helper(须 credential.useHttpPath),
# 不开它每次都会因“请求不完整”拒绝——新测试抓到的真问题。
runuser -u "$SYNC_USER" -- env HOME="$USER_HOME" git config --global credential.useHttpPath true
info "凭证走 chv-authd(不落盘)"
else
: "${GITEA_TOKEN:?guest-env 缺 GITEA_TOKEN(旧路径)}"
echo "chv-sync: 警告:chv-authd 未运行,凭证走旧落盘路径(须用含 authd 的新镜像)" >&2
# token 只落盘进用户家目录的 credential store(0600),
# 不进 git remote URL、不进镜像、不进日志(此处不打印 token)。
local creds="$USER_HOME/.git-credentials"
printf 'https://%s:%s@%s\n' "$GITEA_USER" "$GITEA_TOKEN" "$host" > "$creds"
chmod 0600 "$creds"
chown "$SYNC_USER:$SYNC_USER" "$creds"
fi
if [ -d "$dir/.git" ]; then
info "已 clone:$dir(不自动 pull,改动由用户显式同步)"
exit 0