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

+18 -6
View File
@@ -365,22 +365,34 @@ class HostKeyProvisionTest(ChvGapCase):
def test_write_seed_with_secret_has_no_runcmd(self):
# 带 secret_env 时 guest-env 条目仍须并进同一个
# write_files 列表(单 write_files 键),且 user-data
# 里仍不能出现 runcmd。
# 里仍不能出现 runcmd。feat-chv-muse-p3:GITEA_TOKEN
# 不再走 secret_env,改走 authd_env(独立的 authd-seed
# 条目,0600);guest-env 条目里只剩非 authd 密钥。
with tempfile.TemporaryDirectory() as tmp:
seed_dir = os.path.join(tmp, "seed")
write_seed(seed_dir, "vm1", "PRIV", "ssh-ed25519 AAAAx",
secret_env={"GITEA_TOKEN": "s3cr3t v"})
secret_env={"SUB2API_API_KEY": "gw-key"},
authd_env={"GITEA_TOKEN": "s3cr3t v"})
with open(os.path.join(seed_dir, "user-data")) as fh:
content = fh.read()
self.assertEqual(content.count("write_files:"), 1)
parsed = yaml.safe_load(content)
self.assertNotIn("runcmd", parsed)
self.assertEqual(len(parsed["write_files"]), 3)
self.assertEqual(len(parsed["write_files"]), 4)
paths = [e["path"] for e in parsed["write_files"]]
self.assertIn("/etc/chv/guest-env", paths)
# 密钥值经 shlex.quote 引用后才进文件(值本身在 guest-env
# 条目内是设计内的,见 hostkeys.write_seed)。
self.assertIn("GITEA_TOKEN='s3cr3t v'", content)
self.assertIn("/etc/chv/authd-seed", paths)
# 密钥值经 shlex.quote 引用后才进文件(值本身在条目内
# 是设计内的,见 hostkeys.write_seed);GITEA_TOKEN
# 只在 authd-seed 里,不在 guest-env 里。
entries = {e["path"]: e for e in parsed["write_files"]}
authd_text = entries["/etc/chv/authd-seed"]["content"]
self.assertIn("GITEA_TOKEN=", authd_text)
self.assertIn("s3cr3t v", authd_text)
self.assertEqual(
entries["/etc/chv/authd-seed"]["permissions"], "0600")
self.assertNotIn(
"GITEA_TOKEN", entries["/etc/chv/guest-env"]["content"])
def test_write_seed_uses_atomic_write(self):
# feat-chv-cover100:seed 暂存文件(user-data 含 host