VAIBot Guard (OpenClaw Skill)
This skill provides a local policy decision service plus a vaibot-guard CLI that enforces pre-execution checks and writes a tamper-evident audit log.
Deployment modes
- Local workstation mode (recommended default): run
vaibot-guardas a systemd user service (systemctl --user), optionally coupled toopenclaw-gateway.serviceso it starts whenever OpenClaw starts (typically at login). - VPS / production mode: run
vaibot-guardas a systemd system service (sudo systemctl) under a dedicated user, with stricter sandboxing and boot-time startup.
See: references/ops-runbook.md.
Note: some registries/packagers may strip *.service files. This skill’s install-local command generates the user unit file at install time, so the Clawhub-installed package does not need to include systemd/*/*.service.
Quick Start (local workstation)
0) One-time install + configure (recommended)
Fast path (recommended): one-command local install.
This will:
- install a systemd user service (
~/.config/systemd/user/vaibot-guard.service) - create
~/.config/vaibot-guard/vaibot-guard.env(mode0600) if missing - auto-generate
VAIBOT_GUARD_TOKENif it isn’t already set
node scripts/vaibot-guard.mjs install-local
Or run the interactive configurator only (writes/updates ~/.config/vaibot-guard/vaibot-guard.env with chmod 600):
node scripts/vaibot-guard.mjs configure
1) Start + smoke test
Foreground (quick dev check)
From this skill directory:
# 1) Start the guard service (foreground)
# Reads VAIBOT_GUARD_TOKEN (and other settings) from:
# - env vars, or
# - ~/.config/vaibot-guard/vaibot-guard.env
node scripts/vaibot-guard-service.mjs
In another terminal:
# 2) Precheck + exec (example)
node scripts/vaibot-guard.mjs precheck --intent '{"tool":"system.run","action":"exec","command":"/bin/echo","cwd":".","args":["hello"],"expectedOutputs":["hello"]}'
node scripts/vaibot-guard.mjs exec --intent '{"tool":"system.run","action":"exec","command":"/bin/echo","cwd":".","args":["hello"],"expectedOutputs":["hello"]}' -- /bin/echo hello
Systemd (recommended)
After running install-local, you can manage it with:
systemctl --user daemon-reload
systemctl --user enable --now vaibot-guard
systemctl --user status vaibot-guard --no-pager
Notes:
install-localgenerates the user.serviceunit from an embedded template (so publishing/installing the skill does not need to shipsystemd/*/*.servicefiles).- VPS/system service deployment is still supported; see
references/ops-runbook.md.
2) (Optional) Wire VAIBot Guard enforcement into OpenClaw (plugin bridge)
If you are using the vaibot-guard-bridge OpenClaw plugin/tool approach (deny system.run, allow vaibot_exec), use:
# VAIBOT_GUARD_TOKEN must match what your running guard service expects.
export VAIBOT_GUARD_TOKEN="..."
node scripts/wire-openclaw-bridge.mjs
# then restart gateway
openclaw gateway restart
Components
scripts/vaibot-guard-service.mjs— local HTTP policy serviceGET /healthPOST /v1/decide/exec(precheck)POST /v1/finalizePOST /api/proof(Merkle inclusion proofs)
scripts/vaibot-guard.mjs— CLI entrypoint (run withnode scripts/vaibot-guard.mjs ...)
Required environment (MVP)
- Node.js 18+ on the host
Optional:
VAIBOT_GUARD_HOST(default127.0.0.1)VAIBOT_GUARD_PORT(default39111)VAIBOT_WORKSPACE(defaultprocess.cwd())VAIBOT_GUARD_LOG_DIR(default${VAIBOT_WORKSPACE}/.vaibot-guard)VAIBOT_GUARD_TOKEN(recommended): bearer token required for service endpoints (/v1/decide/exec,/v1/finalize,/v1/flush,/api/proof)VAIBOT_POLICY_PATH(default:references/policy.default.json): policy configuration (deny/approve tokens, allowlisted domains, redaction patterns, and file-mutation posture).VAIBOT_CHECKPOINT_HASH_ALG(reserved): future knob for migrating checkpoint chaining (checkpoint.hash) to SHA3-512. Currently checkpoint chaining uses SHA-256 for consistency.VAIBOT_API_URL(e.g.https://www.vaibot.io/api) to anchor receipts via/proveVAIBOT_API_KEYbearer token for/prove(Authorization:Bearer <API KEY>)VAIBOT_PROVE_MODEL(defaultvaibot-guard):modelfield required by VAIBot/api/prove.VAIBOT_PROVE_MODE(off|best-effort|required, defaultbest-effort). Inrequiredmode, proving is fail-closed for both per-event receipts and checkpoint roots ("no proof, no action"). For security-first deployments, set this torequired.VAIBOT_MERKLE_CHECKPOINT_EVERY(default50): count-based checkpointing interval (events).VAIBOT_MERKLE_CHECKPOINT_EVERY_MS(default600000): time-based checkpointing interval (ms).
Checkpointing is whichever comes first: if either threshold is met and there are new events since the last checkpoint, a new checkpoint root is created. Recommended: 10 minutes and/or a few hundred–few thousand events depending on expected proof frequency.
Rules (MUST FOLLOW)
- Start the guard service (once per host):
node scripts/vaibot-guard-service.mjs
- Before running any risky action, run a precheck:
node scripts/vaibot-guard.mjs precheck --intent '<json>'
-
If the decision is
deny, do not execute. -
If the decision is
approve, require explicit human approval (MVP: stop and surfaceapprovalId). -
If the decision is
allow, execute only via:
node scripts/vaibot-guard.mjs exec --intent '<json>' -- <command...>
- Ensure the run is finalized (the
execcommand auto-finalizes on exit; you can also call it manually):
node scripts/vaibot-guard.mjs finalize --run_id <id> --result '<json>'
Intent JSON (minimum fields)
The guard service requires these keys at minimum:
{
"tool": "system.run",
"action": "exec",
"command": "/usr/bin/uname",
"cwd": "."
}
Recommended additional fields (use them when available):
args: string[]env_keys: string[]network:{ destinations: string[] }files:{ read: string[], write: string[], delete: string[] }correlation:{ agent_id, session_id, trace_id }
Policy
See: references/policy.md
See: references/receipt-schema.md
See: references/checkpoint-schema.md
See: references/idempotency.md
See: references/metadata-indexing.md
See: references/merkle-replay.md
See: references/inclusion-proofs.md
See: references/required-mode.md
Output / receipts
- Decisions + finalize events are appended to hash-chained JSONL logs in
.vaibot-guard/. - These logs are designed to be tamper-evident (each line includes
prevHash).