From df06dbaf7b11741f78828cc1acfc587736183d0e Mon Sep 17 00:00:00 2001 From: Haitao Pan Date: Sat, 6 Jun 2026 14:21:59 +0800 Subject: [PATCH] docs: add vault ssh deploy runbook --- .../vault-github-actions-2026-06-06.md | 10 ++- ...vault-github-actions-ssh-deploy-runbook.md | 84 +++++++++++++++++++ 2 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 docs/operations/vault-github-actions-ssh-deploy-runbook.md diff --git a/docs/operations/vault-github-actions-2026-06-06.md b/docs/operations/vault-github-actions-2026-06-06.md index a3045a6..fc0b3ad 100644 --- a/docs/operations/vault-github-actions-2026-06-06.md +++ b/docs/operations/vault-github-actions-2026-06-06.md @@ -26,8 +26,8 @@ 每个 role 仅绑定本仓库对应的 GitHub OIDC 身份: -- `repository = x-evor/` -- `sub = repo:x-evor/:*` +- `repository = ai-workspace-lab/` +- `sub = repo:ai-workspace-lab/:*` - `bound_audiences = ["vault"]` 每个 policy 仅允许读取自己的 KV 路径。 @@ -49,7 +49,10 @@ - `publish.yml` 改为通过 Vault 读取 `NPM_TOKEN` - `deploy.yml` 改为通过 Vault 读取 SSH 相关密钥 +- `deploy.yml` 已补充 SSH 私钥 `*_B64` 优先读取与多行私钥回退 +- git/source 安装后的版本校验改为读取全局安装目录的 `package.json.version` - 仍保留原有发布和安装逻辑 +- 已通过 deploy workflow 验收 ### xworkmate-bridge @@ -58,8 +61,10 @@ - `GHCR_TOKEN` - `WORKSPACE_REPO_TOKEN` - `SINGLE_NODE_VPS_SSH_PRIVATE_KEY` + - `SINGLE_NODE_VPS_SSH_PRIVATE_KEY_B64` - `SSH_KNOWN_HOSTS` - 保留原有 `workflow_dispatch` 的手动 token 覆盖路径 +- `prepare-ssh.sh` 已改为优先解码 `SINGLE_NODE_VPS_SSH_PRIVATE_KEY_B64`,再回退到原始私钥 ### xworkmate-app @@ -76,6 +81,7 @@ ## 备注 - 本次未在文档中记录任何敏感值 +- SSH deploy key 统一采用 `*_B64` 优先、原始多行 key 回退的模式,详见 `vault-github-actions-ssh-deploy-runbook.md` - 若后续新增仓库,只需补: - 一条 policy - 一条 role diff --git a/docs/operations/vault-github-actions-ssh-deploy-runbook.md b/docs/operations/vault-github-actions-ssh-deploy-runbook.md new file mode 100644 index 0000000..c680bd0 --- /dev/null +++ b/docs/operations/vault-github-actions-ssh-deploy-runbook.md @@ -0,0 +1,84 @@ +# Vault + GitHub Actions SSH Deploy Runbook + +记录日期:2026-06-06 + +本文档记录 GitHub Actions 通过 Vault OIDC 读取 SSH deploy key 的标准模式。文档只记录流程和字段名,不包含任何敏感值。 + +## 适用范围 + +适用于需要从 GitHub Actions SSH 到部署主机的 workflow,例如: + +- `openclaw-multi-session-plugins/.github/workflows/deploy.yml` +- `xworkmate-bridge/.github/workflows/pipeline.yml` + +不需要 SSH 的发布或构建 workflow 仍按普通 Vault secret 读取模式处理。 + +## Vault 字段约定 + +每个仓库从自己的路径读取: + +```text +kv/data/github-actions/ +``` + +SSH deploy key 至少保留两个字段: + +```text +SINGLE_NODE_VPS_SSH_PRIVATE_KEY +SINGLE_NODE_VPS_SSH_PRIVATE_KEY_B64 +``` + +如果仓库有专用别名,也可以同时保留: + +```text +OPENCLAW_SSH_KEY +OPENCLAW_SSH_KEY_B64 +``` + +`*_B64` 是私钥文件内容的 base64 单行编码,GitHub Actions 应优先使用该字段,再回退到原始多行私钥字段。 + +## GitHub Actions 模式 + +workflow 需要: + +- `permissions.id-token: write` +- 使用 `hashicorp/vault-action` +- `method: jwt` +- `jwtGithubAudience: vault` +- `role: github-actions-` +- 在 `secrets` 中读取原始 key 和 `*_B64` key + +落盘时优先解码 `*_B64`: + +```bash +SSH_KEY="" +if [ -n "${SINGLE_NODE_VPS_SSH_PRIVATE_KEY_B64:-}" ]; then + SSH_KEY="$(printf '%s' "${SINGLE_NODE_VPS_SSH_PRIVATE_KEY_B64}" | base64 -d)" +elif [ -n "${SINGLE_NODE_VPS_SSH_PRIVATE_KEY:-}" ]; then + SSH_KEY="${SINGLE_NODE_VPS_SSH_PRIVATE_KEY}" +fi + +printf '%s\n' "${SSH_KEY}" > ~/.ssh/id_rsa +chmod 600 ~/.ssh/id_rsa +ssh-keygen -y -f ~/.ssh/id_rsa >/dev/null +``` + +## 验收步骤 + +1. 触发 deploy workflow。 +2. 确认 `Load Vault secrets` 成功。 +3. 确认 `Verify SSH connectivity` 成功。 +4. 确认远端安装步骤成功。 +5. 如果需要验证安装版本,优先读取安装目录中的 `package.json.version`,不要直接解析 `npm ls -g` 的整行输出。 + +## 故障处理 + +- `Load key ... error in libcrypto`:优先检查 workflow 是否读取并解码了 `*_B64` 字段。 +- `Permission denied (publickey)`:本地用同一把私钥先执行 SSH 验证,再更新 Vault。 +- `vault-action` 报 `valid path and key`:检查 `secrets` 每一行之间是否用 `;` 分隔。 +- git/source 安装后版本校验误判:读取 package manifest 的 `version` 字段。 + +## 已验证记录 + +- `openclaw-multi-session-plugins` deploy run 已通过。 +- `xworkmate-bridge` 已补齐 workflow 与 Vault 字段,后续 deploy run 应按同一模式验收。