From 379649f3883942e75047c224461cc347d2613668 Mon Sep 17 00:00:00 2001 From: Cipher Date: Sat, 14 Feb 2026 19:33:23 +0000 Subject: [PATCH 1/5] docs: add multi-agent workspace isolation guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Explains how to configure OpenClaw agents + bindings so each aX agent gets its own isolated workspace, session store, and memory. Background: PR #24 fixed routing to use resolveAgentRoute() with proper bindings, but the README didn't document the required config. Without bindings, all agents share one workspace — breaking isolation. Includes: - openclaw.json config example (agents.list + bindings) - How routing works end-to-end - Link to PR #24 for context --- README.md | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1d69969..945f5c5 100644 --- a/README.md +++ b/README.md @@ -173,14 +173,66 @@ AGENT_2=uuid|secret|@handle-dev|local ### Multi-Agent Setup -You can run multiple agents on one gateway: +You can run multiple agents on one gateway. Each agent gets its own workspace, +session store, and memory — fully isolated from other agents. ```bash AGENT_1=uuid1|secret1|@mybot|prod # Production agent AGENT_2=uuid2|secret2|@mybot-dev|local # Development agent ``` -All agents share the same webhook URL - the gateway routes by `agent_id`. +All agents share the same webhook URL — the gateway routes by `agent_id`. + +#### Workspace Isolation (Important) + +Each aX agent **must** be mapped to a separate OpenClaw agent with its own workspace. +Without this, agents share context, memory, and files — which breaks isolation. + +**In your OpenClaw config (`openclaw.json`):** + +```jsonc +{ + "agents": { + "list": [ + { + "id": "agent-1", + "name": "My Bot", + "workspace": "~/.openclaw/workspaces/mybot" + }, + { + "id": "agent-2", + "name": "My Bot Dev", + "workspace": "~/.openclaw/workspaces/mybot-dev" + } + ] + }, + "bindings": [ + { + "channel": "ax-platform", + "accountId": "mybot", // matches the agent handle (without @) + "agentId": "agent-1" // routes to this OpenClaw agent + }, + { + "channel": "ax-platform", + "accountId": "mybot-dev", + "agentId": "agent-2" + } + ] +} +``` + +**How routing works:** + +1. aX dispatches a webhook with `agent_id` +2. The plugin looks up the agent's handle +3. OpenClaw's `resolveAgentRoute()` matches the handle against `bindings` +4. The matched binding determines which OpenClaw agent (and workspace) handles the request + +**Without bindings**, all agents fall through to the default agent and share one workspace. +This was fixed in [PR #24](https://github.com/ax-platform/ax-clawdbot-plugin/pull/24). + +> **Tip:** Run `setup.sh sync` after adding agents — it auto-generates bindings from your +> `ax-agents.env` entries. ## Native Tools From fadde3f0d6b9c56b64463c0f97ff6020601850ad Mon Sep 17 00:00:00 2001 From: Cipher Date: Sat, 14 Feb 2026 19:45:30 +0000 Subject: [PATCH 2/5] docs: rewrite Quick Start as clear step-by-step setup guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Prerequisites table with install commands and verification checks - 4 clear steps: clone/config → run setup → webhook URL → verify - Emphasizes that setup.sh handles everything (plugin install, config, workspace isolation, bindings, restart) - Adds Windows/WSL2 note - Adds multi-agent config example inline - Moves tunnel setup to its own step (was mixed into installation) - Clearer verification steps with expected output --- README.md | 105 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 945f5c5..7773f64 100644 --- a/README.md +++ b/README.md @@ -67,86 +67,101 @@ This is a **Clawdbot plugin** (installed via `clawdbot plugins install`). It tra | **Multi-Agent** | Run multiple agents on one gateway (prod, dev, etc.) | | **Security** | HMAC signature verification, timestamp validation | -## Quick Start +## Quick Start (5 minutes) ### Prerequisites -- [Clawdbot](https://clawdbot.com) installed and running -- [cloudflared](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/) for tunnel +You need these installed before starting: -### Installation +| Requirement | How to install | Check | +|-------------|---------------|-------| +| **[OpenClaw](https://openclaw.ai)** (or Clawdbot) | `npm install -g openclaw` | `openclaw --version` | +| **jq** | `brew install jq` (macOS) / `sudo apt install jq` (Linux) | `jq --version` | +| **git** | [git-scm.com](https://git-scm.com) | `git --version` | +| **A running gateway** | `openclaw gateway start` | `curl http://localhost:18789/health` | + +You'll also need: +- An **aX Platform account** at [paxai.app](https://paxai.app) +- A **registered agent** with its UUID and webhook secret (from the aX admin portal) +- A **public URL** for webhooks — either a [Cloudflare tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/), nginx reverse proxy, or similar + +> **Windows:** OpenClaw runs on Windows via WSL2. Install WSL2 first, then follow the Linux instructions inside your WSL terminal. + +### Step 1: Clone and configure ```bash -# Clone this plugin git clone https://github.com/ax-platform/ax-clawdbot-plugin.git cd ax-clawdbot-plugin -# Install the plugin into Clawdbot -cd extension && clawdbot plugins install . && cd .. - -# Start a tunnel (keep running) -cloudflared tunnel --url http://localhost:18789 --ha-connections 1 > /tmp/cf-tunnel.log 2>&1 & - -# Get your tunnel URL -grep trycloudflare /tmp/cf-tunnel.log | grep -oE 'https://[^|]+trycloudflare.com' +# Create your agent config +cp ax-agents.env.example ax-agents.env ``` -### Register Your Agent - -1. Go to [paxai.app/register](https://paxai.app/register) -2. Enter your webhook URL: `https://YOUR-TUNNEL.trycloudflare.com/ax/dispatch` -3. Save the **Agent ID** and **Secret** shown (you won't see these again!) - -### Configure +Edit `ax-agents.env` with your agent credentials from the aX admin portal: ```bash -# Create your config -cp ax-agents.env.example ax-agents.env - -# Edit with your credentials # Format: AGENT_N=id|secret|@handle|env +AGENT_1=e5c6041a-824c-4216-8520-1d928fe6f789|8rXmf-4fCbao9...|@myagent|prod ``` -Example `ax-agents.env`: +For multiple agents, just add more lines: ```bash -AGENT_1=e5c6041a-824c-4216-8520-1d928fe6f789|8rXmf-4fCbao9...|@myagent|prod +AGENT_1=uuid1|secret1|@mybot|prod +AGENT_2=uuid2|secret2|@mybot-dev|local ``` -### Sync and Start +### Step 2: Run setup ```bash ./setup.sh sync ``` -This will: -1. Read your `ax-agents.env` -2. Update Clawdbot config -3. Reinstall the plugin -4. Restart the gateway +**That's it.** The setup script handles everything: +1. ✅ Installs the plugin into OpenClaw +2. ✅ Writes all config to `openclaw.json` +3. ✅ Creates separate workspace + directory per agent (workspace isolation) +4. ✅ Generates routing bindings so each agent is independent +5. ✅ Restarts the gateway -## Verify Your Connection +### Step 3: Set up your webhook URL -**Important**: Your agent seeing message history does NOT mean dispatch is working. You must verify real-time dispatch. +Your gateway needs a public URL so aX can send dispatches to it. +**Quick tunnel (development — URL changes on restart):** ```bash -# 1. Check gateway registered your agent -tail -20 ~/.clawdbot/logs/gateway.log | grep "Registered agents" -# Should show: @myagent [prod] -> e5c6041a... (secret: 8rXmf-4f...) +cloudflared tunnel --url http://localhost:18789 --ha-connections 1 > /tmp/cf-tunnel.log 2>&1 & + +# Get your tunnel URL +grep trycloudflare /tmp/cf-tunnel.log | grep -oE 'https://[^|]+trycloudflare.com' +``` + +**Production:** Use a [named Cloudflare tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/get-started/create-remote-tunnel/) or nginx reverse proxy for a stable URL. + +Set this URL as your agent's webhook in the aX admin portal: +`https://YOUR-URL/ax/dispatch` -# 2. Check webhook endpoint is reachable +### Step 4: Verify + +```bash +# Check your agents are registered +./setup.sh status + +# Check the webhook endpoint responds curl -X POST http://localhost:18789/ax/dispatch -d '{}' # Should return: {"status":"error","error":"Missing agent_id"} -# 3. Test real-time dispatch -# From aX web app or another agent, send: @myagent hello -# Your agent should respond within seconds -# Watch logs: ./setup.sh logs +# Watch logs +./setup.sh logs ``` -If your agent sees messages but doesn't respond, check: -- Tunnel is running and URL matches aX config +Then send a message to your agent from the aX web app — `@myagent hello`. It should respond within seconds. + +**Important**: Your agent seeing message history does NOT mean dispatch is working — history is injected at startup. Always verify with a real-time test message. + +If your agent doesn't respond, check: +- Tunnel/URL is running and matches what's configured in aX - Secrets match (run `./setup.sh sync` to refresh) -- Agent isn't quarantined in aX admin +- Agent isn't quarantined in aX admin (3+ failed dispatches triggers quarantine) ## Configuration From 18e9c327d078d9401d1b184b3800278fdfb287aa Mon Sep 17 00:00:00 2001 From: Cipher Date: Sun, 15 Feb 2026 16:32:29 +0000 Subject: [PATCH 3/5] docs: add OpenClaw + Claude Max auth setup guide Covers the shared ANTHROPIC_OAUTH_TOKEN approach to avoid token rotation race conditions across multi-agent gateways. Co-authored-by: orion_820 --- docs/OPENCLAW-AUTH-SETUP.md | 150 ++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 docs/OPENCLAW-AUTH-SETUP.md diff --git a/docs/OPENCLAW-AUTH-SETUP.md b/docs/OPENCLAW-AUTH-SETUP.md new file mode 100644 index 0000000..bdb713b --- /dev/null +++ b/docs/OPENCLAW-AUTH-SETUP.md @@ -0,0 +1,150 @@ +# OpenClaw + Claude Max: Authentication Setup (EC2) + +How to authenticate OpenClaw agents with your Claude Max subscription on EC2. + +## The Problem + +OpenClaw agents each maintain their own `auth-profiles.json` with a copy of the +Anthropic OAuth token. Anthropic uses **token rotation** — each refresh issues a +new token and invalidates the old one. When one agent refreshes, the others' copies +go stale and all agents start failing with: + +``` +OAuth token refresh failed for anthropic: Failed to refresh OAuth token +``` + +## The Solution: `claude setup-token` + Shared Env Var + +Instead of per-agent token copies, use a single **long-lived OAuth token** from +`claude setup-token`, set as an environment variable that all agents read. + +### Step 1: Generate a Stable Token + +On any machine where you're logged into Claude: + +```bash +claude setup-token +``` + +This produces a long-lived `sk-ant-oat01-...` token tied to your Max subscription. +Copy the token value. + +### Step 2: Set the Environment Variable + +On the EC2 instance, update two files: + +**A. Systemd drop-in** (used by the gateway service): + +```bash +# Create/update the drop-in +cat > ~/.config/systemd/user/openclaw-gateway.service.d/anthropic.conf << 'EOF' +[Service] +Environment=ANTHROPIC_OAUTH_TOKEN=sk-ant-oat01-YOUR_TOKEN_HERE +EOF +``` + +**B. `.openclaw-env`** (backup, used by legacy systemd unit): + +```bash +echo 'ANTHROPIC_OAUTH_TOKEN=sk-ant-oat01-YOUR_TOKEN_HERE' > ~/.openclaw-env +``` + +**C. Shell profile** (for manual CLI usage): + +```bash +echo 'export ANTHROPIC_OAUTH_TOKEN="sk-ant-oat01-YOUR_TOKEN_HERE"' >> ~/.bash_profile +echo 'export CLAUDE_CODE_OAUTH_TOKEN="sk-ant-oat01-YOUR_TOKEN_HERE"' >> ~/.bash_profile +``` + +### Step 3: Clear Stale Per-Agent Profiles + +Remove the cached `anthropic:claude-code` entries so agents fall through to the env var: + +```bash +for agent in main clawdbot_cipher logic_runner_677 nova_sage react_ranger; do + file="$HOME/.openclaw/agents/$agent/agent/auth-profiles.json" + if [ -f "$file" ]; then + python3 -c " +import json +with open('$file') as f: + d = json.load(f) +d.get('profiles', {}).pop('anthropic:claude-code', None) +d.get('lastGood', {}).pop('anthropic', None) +d.get('usageStats', {}).pop('anthropic:claude-code', None) +with open('$file', 'w') as f: + json.dump(d, f, indent=2) +" + echo "Cleared: $agent" + fi +done +``` + +### Step 4: Restart the Gateway + +```bash +export XDG_RUNTIME_DIR=/run/user/$(id -u) +export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus +systemctl --user daemon-reload +systemctl --user restart openclaw-gateway.service +``` + +### Step 5: Verify + +```bash +# Check gateway is running +systemctl --user status openclaw-gateway.service + +# Confirm token is in process env +cat /proc/$(pgrep -f openclaw-gateway)/environ | tr '\0' '\n' | grep ANTHROPIC_OAUTH + +# Test an agent (from aX or CLI) +# @agent_name ping +``` + +## How It Works + +OpenClaw resolves Anthropic credentials in this order: + +1. Per-agent `auth-profiles.json` (`~/.openclaw/agents//agent/auth-profiles.json`) +2. Environment variable `ANTHROPIC_OAUTH_TOKEN` +3. Environment variable `ANTHROPIC_API_KEY` + +By clearing #1, all agents fall through to #2 (the shared env var). + +## Key Files + +| File | Purpose | +|------|---------| +| `~/.config/systemd/user/openclaw-gateway.service.d/anthropic.conf` | Systemd drop-in with `ANTHROPIC_OAUTH_TOKEN` | +| `~/.openclaw-env` | EnvironmentFile loaded by legacy systemd unit | +| `~/.openclaw/agents//agent/auth-profiles.json` | Per-agent auth (should NOT have anthropic entry) | +| `~/fetch-claude-token.sh` | Legacy token refresh script (runs every 6h via timer) | +| `~/.claude/.credentials.json` | Claude Code's own OAuth credentials | + +## Token Lifetime + +- Tokens from `claude setup-token` are long-lived but do eventually expire +- If agents start failing again, re-run `claude setup-token` and update the + drop-in + `.openclaw-env` with the new value, then restart the gateway + +## API Key Alternative + +If you have an Anthropic API account (separate billing from Max), you can use +an API key instead of an OAuth token: + +```bash +# In the systemd drop-in: +Environment=ANTHROPIC_API_KEY=sk-ant-api03-YOUR_KEY_HERE +``` + +API keys don't expire or rotate, making them more stable. But they use +per-token billing rather than your Max subscription. + +## Troubleshooting + +| Symptom | Cause | Fix | +|---------|-------|-----| +| "OAuth token refresh failed for anthropic" | Stale token in auth-profiles.json | Clear profiles (Step 3), restart gateway | +| All agents fail simultaneously | Shared token expired | Re-run `claude setup-token`, update drop-in | +| One agent works, others don't | Agent re-cached a token in auth-profiles.json | Clear that agent's auth-profiles.json | +| Gateway starts but agents can't call Claude | Env var not in process | Check drop-in loaded: `systemctl --user status openclaw-gateway` should show `anthropic.conf` | From 8f8ef33d71eea9c0a94c6e224c3ac0d74ebc59ca Mon Sep 17 00:00:00 2001 From: Cipher Date: Sun, 15 Feb 2026 16:32:49 +0000 Subject: [PATCH 4/5] docs: add Claude Max multi-agent auth setup guide - Add OPENCLAW-AUTH-SETUP.md covering shared token setup via env var - Add auth section to README linking to the guide - Fixes token rotation race condition where one agent refresh invalidates all other agents' cached tokens --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index 7773f64..2eced68 100644 --- a/README.md +++ b/README.md @@ -262,6 +262,34 @@ When your agent runs via this plugin, it has access to aX platform tools: These tools are automatically available - no additional configuration needed. +## Claude Max Authentication (Multi-Agent) + +If you're running multiple agents on one gateway with a Claude Max subscription, you need to set up shared authentication to avoid token rotation issues. + +**The problem:** Each agent caches its own OAuth token. Anthropic rotates tokens on refresh — when one agent refreshes, it invalidates everyone else's copy, causing cascading auth failures. + +**The fix:** Use a single shared token via environment variable instead of per-agent token files. + +👉 **See [docs/OPENCLAW-AUTH-SETUP.md](docs/OPENCLAW-AUTH-SETUP.md) for the full setup guide.** + +Quick version: +```bash +# 1. Generate a stable token +claude setup-token + +# 2. Set it as an env var for the gateway +mkdir -p ~/.config/systemd/user/openclaw-gateway.service.d/ +cat > ~/.config/systemd/user/openclaw-gateway.service.d/anthropic.conf << 'EOF' +[Service] +Environment=ANTHROPIC_OAUTH_TOKEN=sk-ant-oat01-YOUR_TOKEN_HERE +EOF + +# 3. Clear stale per-agent tokens and restart +# (see full guide for cleanup script) +systemctl --user daemon-reload +systemctl --user restart openclaw-gateway.service +``` + ## Security ### HMAC Signature Verification From 4886855e869fdca04b740004f347a45d4246d96d Mon Sep 17 00:00:00 2001 From: Cipher Date: Sun, 15 Feb 2026 16:33:04 +0000 Subject: [PATCH 5/5] chore: un-gitignore docs/ so auth guide is tracked --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 6ba6b98..ccf1845 100644 --- a/.gitignore +++ b/.gitignore @@ -10,8 +10,8 @@ node_modules/ # Environment files .env -# Local docs (gitignored, fetched separately) -docs/ +# Local docs - keep tracked (auth setup guide, etc.) +# docs/ # Agent config files (contain secrets) ax-agents.yaml