Restore the Vault kv/CICD/AI_WORKSPACE_AUTH_TOKEN read in the deploy job
(the key now exists) and resolve the bootstrap token with a clear
precedence: workflow_dispatch input overrides, else Vault value, else
the on-host installer's resolve_unified_auth_token reuses the persisted
~/.ai_workspace_auth_token or generates a new one.
Also fix run-on-host-bootstrap.sh which silently dropped
AI_WORKSPACE_AUTH_TOKEN: it is now written to the remote env payload and
exported, so an input/Vault-provided token is actually honored on the
host instead of being regenerated. Empty stays empty so the no-arg
curl|bash install path still self-generates.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
vault-action ignoreNotFound only suppresses path-level 404, not missing
keys within an existing path. Token is now sourced exclusively from the
ai_workspace_auth_token workflow_dispatch input.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Local MCP debug setup: launcher scripts, config, setup script, and EN/ZH docs.
Secrets live in config/mcp/local-mcp.env (gitignored); commit a sanitized
local-mcp.env.example template instead.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The deploy job ran curl|bash with no AI_WORKSPACE_OFFLINE_MODE -> auto -> stale
offline package, which still ships the pinned-Chrome / root-PGDATA playbooks that
were already fixed in playbooks main. Pipeline kept failing at the Chrome task.
- run-on-host-bootstrap.sh: thread AI_WORKSPACE_OFFLINE_MODE (default off) into the
remote env so the bootstrap git-clones latest main instead of the stale package.
- workflow: add offline_mode input (off|auto|force, default off); flip back to auto
once the offline package is republished with the fixes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously 'Configure remote backend' had `if: TF_STATE_BUCKET != ''`, so when
the gate evaluated empty the step was skipped and terraform silently fell back to
local state — risking state loss on destroy. TF_STATE_* exist in Vault, so make
the remote backend the default required path:
- Validate step now requires TF_STATE_{ENDPOINT,BUCKET,ACCESS_KEY,SECRET_KEY}
- 'Configure remote backend' always runs (renders backend.tf)
- terraform init fails fast if TF_STATE_BUCKET empty (removed local-state else)
- header comment updated: backend keys are required, not optional
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cloudflare R2 S3-compatible backend requires region=auto; the previous
fallback us-east-1 would cause terraform init to fail if Vault key is absent.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Stop checking out the old private mono-repo `ai-workspace-infra`.
- Checkout the split public repositories `ai-workspace-infra/playbooks` and `ai-workspace-infra/iac_modules` separately.
- Remove `CODEX_GITHUB_PERSONAL_ACCESS_TOKEN` (`INFRA_REPO_TOKEN`) dependency from vault as it's no longer needed for public repos.
Documents the YAML->generate.py->terraform->cmdb.json->ansible flow, the FQDN
inventory_hostname contract, the two execution models, the Vault-OIDC pipeline,
the non-empty/fail-fast checks, and the key fixes that make it work end to end.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a 'Validate required secrets' run-step after each job's Vault OIDC
load step. It checks REQUIRED steps.vault.outputs.* are non-empty via
env: mapping (never echoes secret values), and on any empty key prints a
::error:: naming the key + its Vault path then exit 1. The deploy job
requires at least one of ANSIBLE_SSH_KEY_B64 / ANSIBLE_SSH_KEY. Optional
keys (INFRA_REPO_TOKEN, TF_STATE_*) are not validated. Vault path strings
in error messages reference the env.VAULT_KV[_OPENCLAW] vars rather than
hardcoded literals.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
On-host ansible-playbook -c local now uses XWORKMATE_BRIDGE_DOMAIN (sourced from
CMDB service_domains via the pipeline) or the host FQDN as inventory_hostname,
falling back to 127.0.0.1 only when no valid FQDN exists. Keeps -c local.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New optional 'bridge_domain' input overrides; otherwise derive from each host's
cmdb.json host_vars.service_domains (first entry) and inject as
XWORKMATE_BRIDGE_DOMAIN so the host sets /etc/hostname + xworkmate-bridge.caddy
from it (on-host model has no inventory hostvars).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
DEEPSEEK/NVIDIA/OLLAMA_API_KEY live in kv/data/openclaw (not CICD); vault-action
reads them from that path in the same step. Policy grants read on both
kv/data/CICD and kv/data/openclaw.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- VAULT_KV -> kv/data/CICD (shared CICD secrets), map existing keys to outputs:
CODEX_GITHUB_PERSONAL_ACCESS_TOKEN->INFRA_REPO_TOKEN,
SSH_PRIVATE_DEPLOY_KEY[_B64]->ANSIBLE_SSH_KEY[_B64],
CLOUDFLARE_DNS_API_TOKEN direct; VULTR_API_KEY/LLM keys same name.
- docs: policy reads kv/data/CICD; field table maps existing keys; note the
three LLM keys still need to be added to kv/CICD, and SSH_PUBLIC_DEPLOY_KEY
must match hosts.yaml.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- deploy job: read ANSIBLE_SSH_KEY_B64 (preferred) + ANSIBLE_SSH_KEY (fallback)
from Vault, decode/write ~/.ssh/id_deploy and ssh-keygen -y self-check —
matches the org SSH-deploy runbook (avoids multiline-key libcrypto errors).
- docs/operations/vault-github-actions.md: full Vault role/policy/jwt/KV setup
for github-actions-xworkspace-console, mirroring the existing org records.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace GitHub Actions Secrets with HashiCorp Vault (https://vault.svc.plus):
- permissions: id-token: write; auth via hashicorp/vault-action@v2 (method=jwt,
role=github-actions-xworkspace-console, audience=vault) — no static token.
- Each job loads only the keys it needs from kv/data/github-actions/xworkspace-console
(VULTR_API_KEY, INFRA_REPO_TOKEN, ANSIBLE_SSH_KEY, CLOUDFLARE_API_TOKEN,
DEEPSEEK/NVIDIA/OLLAMA_API_KEY, optional TF_STATE_*).
- Backend gating now keys off the Vault output (steps.vault.outputs.TF_STATE_BUCKET).
- Drop unused 'playbook' input (deploy is on-host bootstrap).
Pattern mirrors xworkmate-app/.github/workflows/build-and-release.yml.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Expand the all-in-one setup guide (zh+en) into a full reference of the
bootstrap script's supported options, grouped by purpose: subcommands
(uninstall/--purge), public-exposure & security, unified auth-token chain,
runtime modes, offline package, performance/locks, source/version overrides.
Fix the inaccurate TOKEN var -> AI_WORKSPACE_AUTH_TOKEN (the real precedence
chain). Sourced from scripts/setup-ai-workspace-all-in-one.sh.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- deploy-ai-workspace-iac.yaml: deploy job now ssh-es to each host and runs
the official curl|bash bootstrap locally (host-side ansible -c local,
offline-accelerated), instead of running all-in-one from the runner (which
breaks on roles/agent_skills delegate_to: localhost). provision job kept as
the batch-provision mode.
- docs/operations: record final console fix (local python static backend),
caddy/public-access architecture, and debian13/ubuntu26.04/macOS verification.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Records the IaC->inventory->deploy linkage, offline-package linkage
verification, the local-on-host execution finding, the 5 fixes applied to
playbooks, and the remaining console static-serve + pipeline TODOs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
generate.py moved to vultr-vps/scripts/ and provider/variables/cloud-init to
templates/; run render/inventory from VPS_ROOT via scripts/generate.py, keep
terraform -chdir in the env workdir.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Matrix pipeline that provisions Vultr hosts via iac_modules vultr-vps
ai-workspace env (Terraform), derives the deploy matrix from the rendered
CMDB, deploys per-host with Ansible all-in-one, then syncs Cloudflare DNS.
Pipelining off + PYTHONWARNINGS=ignore for Python 3.13 targets.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>