ci: support customizable AI_WORKSPACE_AUTH_TOKEN in deployment workflow

- Add AI_WORKSPACE_AUTH_TOKEN to Vault KV secret reads (provision + deploy jobs)
- Add ai_workspace_auth_token as optional workflow_dispatch input parameter
- Allow runtime override of auth token (input takes precedence over Vault)
- Include TLDR token generation guidance in workflow description
- Wire token through all-in-one bootstrap with precedence: input > Vault

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
Haitao Pan 2026-06-28 16:10:11 +08:00
parent a661854bb3
commit cc057a6cf9

View File

@ -43,6 +43,15 @@ name: Deploy AI Workspace (IaC + Ansible + Cloudflare)
# ai-workspace-infra/vultr-vps/config/resources/ai-workspace-hosts.yaml
# 的 ssh_keys[].public否则 Terraform 创机后 runner 无法 SSH 登录。
#
# 7. AI_WORKSPACE_AUTH_TOKENLiteLLM 认证 token存储在 Vault
# - 用于 OpenCode ACP adapter 的 LITELLM_MASTER_KEY
# - 存储位置vault kv patch kv/CICD AI_WORKSPACE_AUTH_TOKEN=<your-token>
# - TLDR 生成非常简单:
# • Python: python3 -c 'import uuid; print(uuid.uuid4())'
# • macOS: openssl rand -hex 32
# • Linux: openssl rand -base64 32
# - 部署时自动从 Vault 读取,注入 ansible role 的 acp_opencode_auth_token
#
# ── 流水线结构 ───────────────────────────────────────────────────────────────
#
# provision : 批量起机模式开关terraform_action=apply / run_deploy
@ -114,6 +123,11 @@ on:
required: false
default: true
type: boolean
ai_workspace_auth_token:
description: "自定义覆盖 AI Workspace auth token留空则使用 Vault kv/CICD/AI_WORKSPACE_AUTH_TOKEN— TLDR 生成python3 -c 'import uuid; print(uuid.uuid4())' 或 openssl rand -hex 32"
required: false
default: ""
type: string
# id-token: write 用于 Vault 的 GitHub OIDC(JWT) 认证contents: read 拉代码
permissions:
@ -162,7 +176,8 @@ jobs:
${{ env.VAULT_KV }} TF_STATE_SECRET_KEY | TF_STATE_SECRET_KEY ;
${{ env.VAULT_KV }} TF_STATE_REGION | TF_STATE_REGION ;
${{ env.VAULT_KV }} CLOUDFLARE_DNS_API_TOKEN | CLOUDFLARE_DNS_API_TOKEN ;
${{ env.VAULT_KV }} CLOUDFLARE_API_TOKEN | CLOUDFLARE_API_TOKEN
${{ env.VAULT_KV }} CLOUDFLARE_API_TOKEN | CLOUDFLARE_API_TOKEN ;
${{ env.VAULT_KV }} AI_WORKSPACE_AUTH_TOKEN | AI_WORKSPACE_AUTH_TOKEN
- name: Validate required secrets
env:
@ -314,6 +329,7 @@ jobs:
secrets: |
${{ env.VAULT_KV }} SSH_PRIVATE_DEPLOY_KEY | ANSIBLE_SSH_KEY ;
${{ env.VAULT_KV }} SSH_PRIVATE_DEPLOY_KEY_B64 | ANSIBLE_SSH_KEY_B64 ;
${{ env.VAULT_KV }} AI_WORKSPACE_AUTH_TOKEN | AI_WORKSPACE_AUTH_TOKEN ;
${{ env.VAULT_KV_OPENCLAW }} DEEPSEEK_API_KEY | DEEPSEEK_API_KEY ;
${{ env.VAULT_KV_OPENCLAW }} NVIDIA_API_KEY | NVIDIA_API_KEY ;
${{ env.VAULT_KV_OPENCLAW }} OLLAMA_API_KEY | OLLAMA_API_KEY
@ -329,6 +345,7 @@ jobs:
env:
ANSIBLE_SSH_KEY: ${{ steps.vault.outputs.ANSIBLE_SSH_KEY }}
ANSIBLE_SSH_KEY_B64: ${{ steps.vault.outputs.ANSIBLE_SSH_KEY_B64 }}
AI_WORKSPACE_AUTH_TOKEN: ${{ steps.vault.outputs.AI_WORKSPACE_AUTH_TOKEN }}
DEEPSEEK_API_KEY: ${{ github.event.inputs.use_deepseek == 'false' && '' || steps.vault.outputs.DEEPSEEK_API_KEY }}
NVIDIA_API_KEY: ${{ github.event.inputs.use_nvidia == 'false' && '' || steps.vault.outputs.NVIDIA_API_KEY }}
OLLAMA_API_KEY: ${{ github.event.inputs.use_ollama == 'false' && '' || steps.vault.outputs.OLLAMA_API_KEY }}
@ -341,6 +358,10 @@ jobs:
echo "::error::缺少必需机密 SSH 私钥 (Vault: ${VAULT_KV}/SSH_PRIVATE_DEPLOY_KEY_B64 或 ${VAULT_KV}/SSH_PRIVATE_DEPLOY_KEY至少一个)"
missing=1
fi
# AI_WORKSPACE_AUTH_TOKEN 可选,存在即校验非空。
if [ -n "${AI_WORKSPACE_AUTH_TOKEN:-}" ]; then
echo "AI_WORKSPACE_AUTH_TOKEN: present (will inject as acp_opencode_auth_token)"
fi
if [ "${{ github.event.inputs.use_deepseek || 'true' }}" = "true" ] && [ -z "${DEEPSEEK_API_KEY:-}" ]; then
echo "::error::缺少必需机密 DEEPSEEK_API_KEY (Vault: ${VAULT_KV_OPENCLAW}/DEEPSEEK_API_KEY)"
missing=1
@ -403,6 +424,8 @@ jobs:
# 离线包重新发布后可设为 auto 恢复离线加速。
AI_WORKSPACE_OFFLINE_MODE: ${{ github.event.inputs.offline_mode || 'off' }}
XWORKMATE_BRIDGE_DOMAIN: ${{ github.event.inputs.bridge_domain }}
# AI_WORKSPACE_AUTH_TOKEN: 优先使用 input 自定义值;留空则回退到 Vault 的值
AI_WORKSPACE_AUTH_TOKEN: ${{ github.event.inputs.ai_workspace_auth_token || steps.vault.outputs.AI_WORKSPACE_AUTH_TOKEN }}
DEEPSEEK_API_KEY: ${{ github.event.inputs.use_deepseek == 'false' && '' || steps.vault.outputs.DEEPSEEK_API_KEY }}
NVIDIA_API_KEY: ${{ github.event.inputs.use_nvidia == 'false' && '' || steps.vault.outputs.NVIDIA_API_KEY }}
OLLAMA_API_KEY: ${{ github.event.inputs.use_ollama == 'false' && '' || steps.vault.outputs.OLLAMA_API_KEY }}