openclaw-client-bootstrap
OpenClaw Client Bootstrap
Create and apply a reusable client kit for OpenClaw with strict governance:
- private gateway exposure through Tailscale
- Tailnet-only SSH with non-root logins by default
- Telegram notification channel (sends portal links for approval events)
- SPAPS approval backend with Unclawg portal for human review
- read-only credentials in OpenClaw
- explicit write-gateway contract for all external mutations
Use This For
- New OpenClaw client box bootstraps on a fresh droplet
- Co-located OpenClaw container setups on an existing box
- Recovery, rotation, or governed re-bootstrap of an existing client kit
Do Not Use This For
- Day-to-day waitlist or portal admin actions
- Discovery, feed, or revision-processing runtime flows
- Upstream OpenClaw docs drift audits without deployment work
AI Runtime-First Skill Split
Treat tracked skills as AI runtime instructions, and keep operator/admin runbooks private.
- Runtime skills must be wrapper-only (
tools.exec.security: "allowlist"+safeBins). - Runtime skills should fail closed when required wrapper bins are missing.
- Keep local project overlays in
modes/(gitignored). - Keep admin-only skills (for example
unclawg-admin) gitignored/private. - Keep deploy secrets gitignored/private. If you automate runtime sync in CI, keep host keys, SSH material, and live deploy targets in your own secret store. Do not commit live-instance workflows to the public repo.
- Do not point a production claw at
../skillswholesale; curate a runtime-safe subset.
Architectural Decision First
Before collecting inputs or building a kit, decide:
New droplet (Option A) — full isolation, separate Tailscale node, separate billing. Best for client deployments or high-volume autonomous claws.
Existing droplet, new Docker container (Option B) — co-located, separate Telegram bot, separate agent key, separate SPAPS agent. Best for purpose-specific internal claws added to an existing box (e.g., a content-creation agent alongside an ops agent). Saves ~$12-18/mo.
See references/deployment-workflow.md — "Architectural Decision" section for isolation guarantees, trade-offs, and Option B deploy steps (skip bootstrap-do.sh + Tailscale, use a different systemd service name).
Also decide storage before building the kit: root disk (default, free), DO Block volume per claw ($1-2/mo, detachable — best if you may migrate later), or shared volume with per-claw subdirs ($1/mo for co-located claws). See "Storage Decision" section in the same file.
On Trigger: Instantiate the Kit
Resolve the bundled generator script, then create a client kit directory.
GEN="$(ls ~/.codex/skills/openclaw-client-bootstrap/scripts/new_client_kit.sh ~/.claude/skills/openclaw-client-bootstrap/scripts/new_client_kit.sh ./scripts/new_client_kit.sh 2>/dev/null | head -1)"
bash "$GEN" --dest /tmp/<client>-openclaw --interactive
If ./scripts/... is used, run the command from the skill directory.
Required Inputs Before Deployment
Collect these before touching the droplet:
- Client name and environment label
- Telegram operator user ID allowlist
- Telegram group chat ID (and optional topic ID)
- Telegram bot token (from BotFather)
- SPAPS credentials (API URL, API key, agent ID, agent secret)
- Unclawg portal URL
- Tailscale auth key and node hostname
- Integration inventory with read-only scopes
Reference: references/deployment-workflow.md
Customize the Kit
- Fill
.envvalues (including SPAPS credentials). - Replace Telegram placeholders in
openclaw.json:{{TELEGRAM_ALLOWED_USER_ID}}{{TELEGRAM_GROUP_CHAT_ID}}- Optional: add
topicIdper group entry when topic-scoped. - Keep
approvals.exec.targets[*].toconcrete (numeric ID or explicit chat ID), not${env:...}.
- Review
SOUL.md,AGENTS.md, andUSER.mdfor client-specific constraints. - Keep
security/WRITE_GATEWAY_CONTRACT.mdintact unless compliance requires stricter rules. - For any new endpoint + skill combo, follow
security/PERMISSIONS_PLAYBOOK.md(wrapper + allowlist pattern).
Review / Grade Implementation
Run the review script for a second-pass quality check against the review rubric:
REV="$(ls ~/.codex/skills/openclaw-client-bootstrap/scripts/review_kit.sh ~/.claude/skills/openclaw-client-bootstrap/scripts/review_kit.sh 2>/dev/null | head -1)"
bash "$REV" --skill # review the skill template
bash "$REV" /tmp/<client>-openclaw # review a generated kit
bash "$REV" --live # SSH into droplet and review live deployment
bash "$REV" --live openclaw@<tailscale-ip> # specific host
bash "$REV" --live --host <tailscale-ip> --ssh-user aiops # dedicated collab login
bash "$REV" --live --service openclaw-<claw>.service --home /home/<claw-user>/.openclaw --user openclaw
bash "$REV" --live --strict # production gate: missing SPAPS/portal vars fail
Three modes:
--skill/ default: 44 file-based checks across config, env, scripts, docs, generator, validator/path/to/kit: same checks on a generated kit--live: SSHes into the droplet viareview_live.shand runs 30+ checks against the running deployment (service health, Node/Docker, live config schema, SPAPS/portal connectivity, Tailscale, security posture, recent logs). Auto-detects host from localreferences/deployed-instances.mdwhen present.
Talking to Agents via CLI (Debug & Bug-Fixing)
Use the bundled scripts/talk.sh for all agent interaction, log tailing, and SSH access. It reads references/deployed-instances.md automatically — no manual env var wrangling.
TALK="$(ls ~/.codex/skills/openclaw-client-bootstrap/scripts/talk.sh \
~/.claude/skills/openclaw-client-bootstrap/scripts/talk.sh \
./scripts/talk.sh \
2>/dev/null | head -1)"
bash "$TALK" --list # see all claws + live agent IDs
bash "$TALK" --message "what work is queued?" # message primary claw
bash "$TALK" --claw my-claw --message "hello" # message a co-located claw
bash "$TALK" --claw example-claw --message "follow up" --session-id <id> # continue thread
bash "$TALK" --claw example-claw --tail # tail logs live (Ctrl-C to stop)
bash "$TALK" --claw example-claw --logs 100 # last 100 log lines
bash "$TALK" --health # health summary for all claws
bash "$TALK" --health --claw example-claw # health summary for one claw
bash "$TALK" --health --emit-logs --log-dir ~/.openclaw/logs --log-prefix openclaw # health + persisted snapshots
bash "$TALK" --ssh # plain SSH into the droplet (non-root)
bash "$TALK" --ssh-user aiops --ssh # use dedicated collab user
bash "$TALK" --claw example-claw --ssh # SSH with claw env pre-loaded
Positional shorthand: talk.sh example-claw "message" is equivalent to --claw example-claw --message "message".
Agent IDs vs persona names: The --agent value (auto-discovered from agents list) is the agent config ID like content-creator. The persona name lives in SOUL.md — these are different. --list shows both.
Co-located claws: talk.sh handles the OPENCLAW_STATE_DIR / OPENCLAW_CONFIG_PATH env var override automatically. --ssh --claw <name> drops you into a shell with those vars already exported.
Gateway 1006 fallback: If the gateway WebSocket closes with code 1006, openclaw agent falls back to embedded mode. The response is still valid — but check journalctl -u <service> -n 50 to investigate the underlying issue.
Additional flags: --thinking medium for more deliberate reasoning, --agent <id> to override auto-discovery, --json for machine-readable --health output.
For local integration workflows, use:
--emit-logs, --log-dir, and --log-prefix to persist remote claw health snapshots.
Provider/Auth Rotation (Codex/OpenAI/OpenRouter/Anthropic)
Use scripts/update-oauth-token.sh as the single path for credential updates across co-located claws.
# Codex OAuth (default): ~/.codex/auth.json -> OPENAI_API_KEY
bash scripts/update-oauth-token.sh --dry-run
bash scripts/update-oauth-token.sh
bash scripts/update-oauth-token.sh --ssh-user aiops
# Direct OpenAI API key (preferred when OAuth is org-restricted)
OPENAI_API_KEY=sk-proj-... bash scripts/update-oauth-token.sh --openai
# OpenRouter key
OPENROUTER_API_KEY=sk-or-v1-... bash scripts/update-oauth-token.sh --openrouter
# Anthropic swap (stdin preferred)
echo "sk-ant-..." | bash scripts/update-oauth-token.sh --anthropic
What this script now enforces:
- Updates shared env (
<openclaw-home>/shared.envby default) and each claw.env - For Codex, writes canonical
auth-profiles.jsonstore (version/profiles/order) foropenai-codexunder every agent dir - Warns on model/provider mismatch (
openai|openai-codexvsopenrouter/*vsanthropic/*) - Warns if
agents.defaults.model.reasoningEffortexists (can triggerUnknown config keyson this runtime)
If you hit OpenAI scope errors like Missing scopes: api.responses.write, switch from --codex to:
--openaiwith a direct OpenAI API key, or--openrouterwithopenrouter/*model IDs.
Do not hand-edit auth-profiles.json unless diagnosing parser behavior.
Deterministic Recovery Order
When a claw fails after provider/model changes, recover in this exact order:
- Fix model in each
openclaw.json(agents.defaults.model.primaryonly). - Run
bash scripts/update-oauth-token.sh ...for the target provider. - Restart services (script does this unless
--no-restart). - Verify:
bash scripts/talk.sh --listbash scripts/talk.sh --healthbash scripts/talk.sh --health --require-root-proof --json(definitive SSH/UFW proof; fails if checks are inferred)bash scripts/talk.sh --claw <name> --new --message "Reply ONLY: OK"
If talk.sh says Could not auto-discover agent ID, re-run with --agent <id> from --list.
Continuous Improvement Loop (Use skill-issue)
After every incident or rollout, run this loop to keep the bootstrap skill accurate:
- Audit current template and scripts
bash scripts/review_kit.sh --skill
- Audit each live claw
bash scripts/review_live.sh --host <ip> --service <unit> --home <openclaw-home> --user <app-user>
- Capture drift and breakages
- Record root cause + fix in
references/deployment-workflow.mdand update template assets/scripts
- Record root cause + fix in
- Patch the reusable kit, not just the live box
- Update
assets/client-kit/*, then sync any private instance snapshots in your ignoredassets/instances/<claw>/
- Update
- Re-validate
bash scripts/validate_client_kit.sh assets/client-kitbash scripts/review_kit.sh --skill
Validate Before Shipping
Run the bundled validation script against the generated kit:
VAL="$(ls ~/.codex/skills/openclaw-client-bootstrap/scripts/validate_client_kit.sh ~/.claude/skills/openclaw-client-bootstrap/scripts/validate_client_kit.sh ./scripts/validate_client_kit.sh 2>/dev/null | head -1)"
bash "$VAL" /tmp/<client>-openclaw
Reject the deployment if:
- placeholders remain in
openclaw.json - placeholder secrets remain in
.env - removed config keys detected (v2026.2.15 schema violations)
- any kit script fails shell syntax checks
Deploy Workflow
Use the generated kit's scripts in this order on the droplet:
scripts/01-bootstrap-do.shscripts/02-install-tailscale.shscripts/03-install-openclaw.shscripts/04-validate.sh- Optional for shared operator sessions:
scripts/05-setup-collab-tmux.sh
Then verify Telegram notification delivery and SPAPS/portal connectivity.
Cloud firewall requirement: remove public 22/tcp and rely on Tailnet SSH only.
Reference: references/deployment-workflow.md
Governance Rules (Do Not Relax By Default)
- OpenClaw stores read-only credentials only.
- External writes are proposed, never executed directly.
- Write execution requires human approval through the Unclawg portal, backed by SPAPS.
- Operator approvals must be logged with identity, timestamp, payload hash, and result.
Reference: references/read-only-governance.md
Deployed Instances
Two-tier tracking — non-secret config committed, secrets server-only:
assets/instances/<claw-name>/— committed source of truth for each claw'sopenclaw.json,SOUL.md,AGENTS.md,USER.md,.env.example. If the droplet root disk is lost, redeploy from here.references/deployed-instances.md— private instance registry with IPs and connection details (gitignored).envon server — real secrets, never committed
See assets/instances/README.md for the full pattern and redeploy steps.
After bootstrapping any new claw: copy its non-secret files into assets/instances/<claw-name>/ and commit.
Minimum Droplet Specs
- RAM: 2 GB minimum (gateway uses ~800MB; 1GB will OOM)
- Swap: 2 GB recommended
- Docker: Required for agent sandbox mode
- Node heap: Set
NODE_OPTIONS=--max-old-space-size=768in systemd service
Config Schema Notes (v2026.2.15+)
The kit template may need these fixes for current OpenClaw versions:
channels.pairingis not a valid channel — usechannels.telegram.groupPolicy+groupAllowFrom+groups- Telegram token key is
botToken, nottoken tools.exec.askexpects"off"|"on-miss"|"always", not an arraytools.policyMode,tools.exec.fallback,tools.exec.rulesare not recognized — do not add themtools.elevated.require/allowWhenRequestedByare not recognized; usetools.elevated.enabled+tools.elevated.allowFrom.telegram- Run
tailscale set --operator=<app_user>for Tailscale serve permissions
Updates for v2026.2.17–2026.2.18
tools.exec.safeBinsrequired — now enforced; entries must be executable names (e.g.["jq", "grep", "cut", "sort", "uniq", "head", "tail", "tr", "wc", "echo", "printf"]), not directory paths like/usr/bin. Missing or path-style entries can causeexec denied: allowlist miss.- Ask mode for allowlist security — when using
tools.exec.security: "allowlist"for autonomous reads, usetools.exec.ask: "on-miss"so non-allowlisted commands route to approvals instead of hard-denying. - Approval recipient interpolation — avoid
${env:...}inapprovals.exec.targets[*].to; set a concrete Telegram user/chat ID. - Cron webhook auth token —
SPAPS_WEBHOOK_AUTH_TOKENis now supported for authenticated webhook delivery to SPAPS. Add to.envand wire into any cron channel config. - SSRF guards on cron webhooks — v2026.2.18 blocks private RFC1918 ranges, NAT64, 6to4, and Teredo in webhook POST targets.
SPAPS_API_URLmust be a public or Tailscale-routable hostname (not a raw private IP). - Model forward compat — pin to a runtime-supported model id (for example
anthropic/claude-haiku-4-5-20251001on OpenClaw 2026.2.17). Validate from live logs before rollout. - Telegram inline button styles — approval notifications can use
primary,success,dangerbutton styles for Approve/Reject UX. - Co-located claws — use
APP_HOME,OPENCLAW_HOME, andOPENCLAW_SERVICE_NAMEwhen installing additional claws on the same droplet. - Native approval forwarding schema — current runtime supports
approvals.exec.mode: session|targets|both; avoid legacyspapsmode blocks inopenclaw.json. - Runtime placeholders —
{{MediaPath}},{{Prompt}},{{MaxChars}}are valid runtime tokens for CLI media models; do not treat these as unresolved template placeholders.
Updates for v2026.2.19–v2026.2.26
- BREAKING: SafeBins trusted directory enforcement —
tools.exec.safeBinsentries must resolve from trusted bin directories (default:/bin,/usr/binonly). Custom bin paths (e.g./home/openclaw/.openclaw/bin) require explicit opt-in viatools.exec.safeBinTrustedDirs. Without this, custom safeBin entries will fail resolution at runtime. - BREAKING:
sortandgrepremoved from default safe bins — upstream hardened defaults to removesort(file write via-o) andgrep(recursive reads). Explicitly listing them in config still works but triggersopenclaw doctorwarnings. Keep them if needed for read-only analysis, but ensuresafeBinTrustedDirscovers their parent directory. - BREAKING: Heartbeat
directPolicy— new keyagents.defaults.heartbeat.directPolicy(allow|block) replaces DM toggle. Default changed toallowin v2026.2.24. Set"block"if DM heartbeat delivery is undesired for client claws. - BREAKING: Docker container namespace join blocked —
network: "container:<id>"blocked by default. Break-glass:agents.defaults.sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true. - BREAKING: DM allowlist enforcement tightened —
dmPolicy: "allowlist"with emptyallowFromnow silently drops all DMs (was permissive). Always populateallowFromwhen usingallowlistpolicy.openclaw doctor --fixrestores from pairing-store. - Telegram
streamModedeprecated — replace"streamMode": "partial"with"streaming": true. Legacy values auto-mapped but deprecated since v2026.2.21. - Browser SSRF policy key renamed —
browser.ssrfPolicy.allowPrivateNetworkrenamed tobrowser.ssrfPolicy.dangerouslyAllowPrivateNetwork.openclaw doctor --fixauto-migrates. - Secrets management — new top-level
secretsconfig block (secrets.providers,secrets.defaults) for env/file/exec secret sources.openclaw secrets audit/configure/apply/reloadCLI workflow available. - Plugin entries resilience —
plugins.entries.*with unknown IDs now logs warnings instead of crash-looping gateway boot. - Node exec approvals hardened — structured
commandArgvapprovals forhost=node,GIT_EXTERNAL_DIFFblocked in host env keys. - Auth profile alias normalization —
mode -> type,apiKey -> keyaliases accepted inauth-profiles.json. openai-codex-responsesaccepted in config model API schema.session.parentForkMaxTokens— default100000(0disables). Prevents oversized parent-session inheritance from bricking thread sessions.meta.lastTouchedAtaccepts numeric timestamps — coercesDate.now()values to ISO strings for forward compat.gateway.http.securityHeaders.strictTransportSecurity— optional HSTS header for direct HTTPS deployments.
Bundled Assets
The complete production template lives in:
assets/client-kit/openclaw.jsonassets/client-kit/.env.exampleassets/client-kit/SOUL.mdassets/client-kit/AGENTS.mdassets/client-kit/USER.mdassets/client-kit/checklists/*assets/client-kit/security/WRITE_GATEWAY_CONTRACT.mdassets/client-kit/security/PERMISSIONS_PLAYBOOK.mdassets/client-kit/scripts/*
More from build000r/skills
unclawg-internet
Run self-service OpenClaw onboarding with browser device auth, agent machine-key provisioning, a soul interview, and discovery-mode setup. Use for "/unclawg-internet", "set me up", "connect to openclaw", "onboard me", "sign up for openclaw", or approval-gated setup.
15domain-scaffolder-backend
|
7unclawg-discover
Run multi-platform customer discovery across Reddit, Hacker News, Twitter/X, and LinkedIn, then output a ranked engagement feed for downstream workflows. Use for "/unclawg-discover", "find customers", "find leads", "find posts to reply to", "build engagement queue", or agent-builder prospecting.
3remotion-best-practices
Best practices for Remotion - Video creation in React. Use when working with Remotion compositions, animations, sequences, or video rendering. Covers project setup for a shared Remotion hub, animation patterns, timing/interpolation, audio, captions, and media handling.
3divide-and-conquer
Decompose complex work into independent parallel sub-agents with no write overlap, synthesize or consume a `WORKGRAPH.md` execution artifact, and launch describe-style worker briefs before review. Use before spawning multiple agents for multi-file, multi-domain, or naturally parallel tasks.
3openclaw-docs-audit
Audit openclaw-client-bootstrap config and skill guidance against the latest upstream OpenClaw releases, then report ranked drift. Use for "audit openclaw", "check openclaw docs", "openclaw drift", "config freshness", "what changed in openclaw", or "/openclaw-docs-audit".
3