The multi-user control layer for OpenClaw. Identity, access control, quota enforcement, security hardening, audit trails, and deployment ergonomics — without rewriting the runtime.
OpenClaw is a powerful AI assistant runtime, but it was built for one operator. The moment you put it in front of real users, you need to answer: who is this person, are they allowed to be here, how do we stop them from draining the budget, and what happened when something goes wrong?
ClawHive is a thin Router that sits in front of OpenClaw and handles all of that. It verifies every webhook, deduplicates events, blocks injection attacks, resolves tenant identity, enforces access rules, checks budgets, and audits everything. Then it gets out of the way.
v0.1 trust model: ClawHive assumes a trusted operator. All tenants share a single process, the operator has full access to user sandboxes and data, and the Docker socket is mounted for sandbox management. The included AWS/Terraform deployment is a reference architecture, not a hardened multi-tenant isolation boundary. Provider-side spend limits remain the final cost backstop.
- Multi-channel ingress — Slack, Telegram, and WhatsApp (Twilio) webhook handling with per-channel signature verification
- Per-channel identity — each channel auto-provisions a separate user and agent. Cross-channel linking is available in v0.1 via self-service link codes and the tenant API; fully automatic identity resolution is still future work
- Access control — three-state model (pending/approved/suspended) with invite code onboarding
- Security pipeline — prompt injection blocking (all channels, inbound), event deduplication, outbound response scanning for SSRF patterns, dangerous commands, and credential leaks (detect + audit, not inline blocking — see Security)
- Token and cost governance — per-tenant monthly cost quota enforced before the LLM call
- Audit trail — structured events for every security-relevant action, dual-persisted to PostgreSQL + JSON logs
- Admin dashboard — server-rendered UI for tenant management, invite codes, quota controls, audit log viewer
- Admin API — full REST API for all admin operations, with JWT/API key/session cookie auth
- OpenClaw integration — HTTP forwarding + WebSocket RPC for config management, automatic agent provisioning, Ed25519 device authentication
- Deployment — Docker Compose for local development, reference Terraform for AWS (ECS + RDS + EFS + API Gateway)
npm install
cp env.example .env # if using bundled Postgres, keep DATABASE_URL on localhost:5433
docker compose up -d postgres openclaw
npm run migrate
npm run devVerify: curl http://localhost:3000/health
docker compose --profile sandbox-build build sandbox-image sandbox-browser-image
docker compose up -d
docker compose exec router npx tsx scripts/migrate.ts
docker compose exec router npx tsx scripts/bootstrap.tsRouter at http://localhost:3001, OpenClaw at http://localhost:18789.
npm run bootstrap
# Or: POST /api/v1/auth/token with Authorization: Bearer <ADMIN_API_KEY>Channels (Slack · Telegram · WhatsApp)
│
▼
┌──────────────────────────────────────────────────┐
│ Router │
│ Verify → Dedupe → Injection check → │
│ Resolve tenant → Quota → Ack 200 → Forward │
└────────────────────┬─────────────────────────────┘
│
▼
OpenClaw Runtime(s)
Per-user agents, workspaces, sandboxes
│
▼
PostgreSQL · Filesystem · Secrets
Every user gets their own OpenClaw agent ID. The Router maps each request via a single DB lookup: channel + user_id → tenant → agent_id. New users are auto-provisioned on first contact.
The Router is the one piece that stays no matter how the backend evolves.
| Channel | Status | Verification |
|---|---|---|
| Slack | Tested end-to-end | HMAC-SHA256 + 5min replay protection |
| Telegram | Tested end-to-end | Shared secret, retry-resilient forwarding (5 attempts, exponential backoff) |
| WhatsApp (Twilio) | Implemented, not yet validated against live traffic | HMAC-SHA1 request signature |
| Discord | Not yet implemented | Planned |
| Web | Not yet implemented | Planned |
Telegram webhook verification requires TELEGRAM_SECRET_TOKEN to be configured. If it is unset, ClawHive rejects Telegram webhook traffic instead of accepting unauthenticated updates.
The pipeline (verify → dedupe → inject check → resolve → gate → quota → forward) is channel-agnostic. Adding a channel means adding a webhook route, a verifier, and a user ID extractor.
Defaults are conservative. Injection is blocked, registration is closed unless explicitly opened.
Inbound (blocks before forwarding):
| Layer | Enforcement | What it does |
|---|---|---|
| Webhook verification | Block | Constant-time signature comparison (timingSafeEqual) per channel. Invalid signatures return 401/403 |
| Replay defense | Block | 5-minute timestamp window (Slack), atomic deduplication (all channels). Duplicates are silently dropped |
| Prompt injection | Block | Multi-pattern regex detection (extraction, role manipulation, delimiter injection, encoding). Default policy: block |
| Access gate | Block | pending/approved/suspended with invite code onboarding. Unapproved users cannot reach the runtime |
| Quota enforcement | Block | Pre-call monthly cost check ($20 default). Check-then-forward, not atomic — concurrent requests can overshoot |
Outbound (detect + audit after response):
| Layer | Enforcement | What it does |
|---|---|---|
| Command/SSRF scanning | Detect | Blocklist patterns for dangerous commands, cloud metadata endpoints, sensitive file paths. Logged + audited, not inline-blocked |
| Credential pattern detection | Detect | Known API key patterns (sk-ant-, xoxb-, ghp_, AKIA) in WhatsApp responses. Slack/Telegram are not scanned — OpenClaw replies directly to those channels |
| Audit | Always-on | Every security-relevant action persisted to PostgreSQL + structured logs. Gracefully degrades to log-only |
Outbound controls scan the OpenClaw response after delivery (WhatsApp path) or after the proxy forward returns (Slack/Telegram path). They flag and audit violations but do not prevent the response from reaching the user. Inline outbound blocking is a future roadmap item.
| Service | Port | Purpose |
|---|---|---|
router |
3001 → 3000 | ClawHive Router (Hono) |
openclaw |
18789 | OpenClaw runtime |
postgres |
5433 → 5432 | PostgreSQL 16 |
cd infra/terraform
cp terraform.tfvars.example terraform.tfvars
cd ../scripts && ./deploy.shCreates: ECS on EC2, API Gateway HTTP API, RDS PostgreSQL 16, EFS, Secrets Manager, CloudWatch. Teardown: ./infra/scripts/destroy.sh. Full config in infra/.
What ships in v0.1:
- Structured JSON logging (Pino) with tenant IDs, correlation IDs, timings
- In-memory request/forwarding/quota/injection counters via admin API
- Full audit trail in PostgreSQL, queryable via API and dashboard
Planned: Prometheus/CloudWatch export, event loop latency, sandbox metrics, provider error rates, per-tenant cost dashboards. See Future Releases.
src/
├── index.ts # Bootstrap: DB, OpenClaw, HTTP server
├── config.ts # Typed env config with validation
├── db.ts # PostgreSQL connection pool
├── router/
│ ├── app.ts # Hono app composition
│ ├── middleware/ # auth, rate-limit, dedupe
│ └── routes/ # health, webhooks, tenant, admin, dashboard
├── identity/ # resolve, store, access, invite
├── openclaw/ # client, config-patcher, device-identity, session-usage
├── security/ # verify, injection, audit, policy, credentials
├── quota/ # governor (per-tenant token/cost enforcement)
└── observability/ # logger, metrics
A single PostgreSQL migration (001_initial) builds the full schema. Run with npm run migrate.
- Runtime adapter boundary — keep the OpenClaw adapter but formalize a runtime interface so the governance layer can support additional runtimes over time
- Outbound post-processing/inspection — add asynchronous response scanning and policy alerts from session/event streams where inline interception is not possible
- Cost analytics and budget operations UI — add burn-rate trends, anomaly detection, per-tenant forecasting, and budget control actions
- SSO/OIDC + org RBAC — add enterprise identity and role-based access control for team-scale administration
- Additional channels — Discord, Web/WebSocket, WhatsApp live validation
- Observability — Prometheus/CloudWatch metrics export, event loop and sandbox metrics, provider error tracking, and per-tenant cost dashboards
- Stronger isolation — add isolation tiers, including container-per-user tenancy and stricter sandbox/network policies
- Hard cost limits — per-user max-cost quota with sandbox shutdown on breach
- Extract security/quota modules — publish reusable packages for injection detection, credential scanning, and quota governance
Operational notes for current deployment.
Slack socket mode must be disabled
In HTTP webhook mode, appToken must not be set — otherwise OpenClaw receives every event twice (HTTP + socket). The startup script handles this automatically.
Device pairing
The Router generates an Ed25519 device identity on first startup. The public key is shared with OpenClaw via a read-only volume mount for gateway pairing. When pre-seeding succeeds, allowInsecureAuth is automatically disabled.
Cron tool not exposed (OpenClaw bug)
The cron tool is in the sandbox allow list and sandbox explain confirms it, but it's not injected into the agent at runtime. Workaround: use /remind in Slack or HEARTBEAT.md. Fix is wip.
Sandbox image hardening (TODO)
The sandbox currently includes build tools and full outbound internet. Production deployments should drop build tools, restrict network, and add Docker resource limits.
SECURITY.md— security policyinfra/OPERATIONS.md— operations runbookCONTRIBUTING.md— contributing guideCODE_OF_CONDUCT.md— code of conductMAINTAINERS.md— maintainership and ownershipCHANGELOG.md— changelog
