* feat(webhooks): HTTP webhooks to trigger agents with HMAC auth and durable callbacks
Add multi-tenant HTTP webhook endpoints for agent triggering:
- /v1/webhooks/message: send messages to channels
- /v1/webhooks/llm: sync/async LLM prompts with HMAC-signed callbacks
- HMAC-256 + bearer token authentication
- Rate limiting and tenant isolation
- Durable callback worker with exponential backoff
- PG 000056 + SQLite schema v25 migrations
- Unit + integration tests, P0 tenant isolation invariants
- Channel media capability helpers for attachment routing
- Comprehensive webhook documentation and i18n strings
* fix(webhooks): address post-review findings (K1-K10)
Comprehensive post-merge fixes addressing 10 blocking code review issues
and 2 adversarial re-audit findings in webhook-agent-triggering feature:
K1: Fix auth middleware tenant context lookup sequencing — move
tenant context injection before authenticate() call to prevent
unscoped secret lookups.
K2: Canonicalize JSON payload format for jsonb compatibility across
PostgreSQL and SQLite — ensure consistent serialization without
whitespace variance to prevent hash mismatches.
K3: Add fail-closed JSON parsing in body hash extraction with explicit
error handling for malformed payloads before HMAC verification.
K4: Fix worker queue wedge by properly draining slot reservations
when delivery succeeds, preventing permanent slot occupancy.
K5: Implement lease-token optimistic concurrency control to prevent
duplicate webhook delivery under high concurrency or retry storms.
K6: Add AES-256-GCM encrypted secret storage at rest with fail-fast
skip-mount when GOCLAW_ENCRYPTION_KEY environment variable unset.
K7: Implement IP allowlist enforcement supporting both CIDR ranges
and exact IP matching with proper X-Forwarded-For parsing.
K8: Add HMAC replay nonce cache (5min expiry, non-blocking async flush)
to prevent request replay attacks on webhook handler.
K9: Fix invariant test schema selection — replace hardcoded assumption
with explicit schema name from config to support multi-schema testing.
K10: Consolidate rate limiters into single shared instance to prevent
per-endpoint limiter starvation and ensure fair rate limiting.
New database migrations:
- 000057: webhook_calls.lease_token for optimistic concurrency
- 000058: webhooks.encrypted_secret_key for AES-256-GCM encryption
New i18n keys: MsgWebhookIPDenied, MsgWebhookEncryptionUnavailable
(with English, Vietnamese, Chinese translations).
New modules:
- internal/http/webhooks_payload.go: JSON canonicalization + body hash
- internal/http/webhooks_nonce.go: Replay nonce cache implementation
- internal/http/webhooks_idempotency_test.go: Integration tests
Documentation updates:
- docs/webhooks.md: §13-14 security sections, encryption flow
- docs/00-architecture-overview.md: webhook subsystem security overview
- docs/codebase-summary.md: webhook security patterns
- docs/project-changelog.md: webhook fixes changelog
Test coverage: 53 webhook tests + 4 P0 invariant tests all passing.
No tenant isolation violations. All security gates enforced.
* docs(journals): webhook feature ship + fix cycle entries
* fix(webhooks): address Claude review findings
- webhooks_llm.go: remove misleading ptr() helper; use &completedAt
pattern for error-path audit rows (matches success path)
- webhooks_auth.go: wrap TouchLastUsed context in WithoutCancel so
background DB update isn't cancelled when HTTP response completes
- store GetByIDUnscoped (PG+SQLite): add NOT revoked / revoked = 0
filter for defense-in-depth parity with GetByHashUnscoped
- webhooks/sign.go: fix package doc — HMAC key is raw plaintext
secret bytes, not hex-decoded SHA-256
- webhooks_admin.go: check auth before encKey guard to avoid leaking
config state to unauthenticated callers
- webhooks_ratelimit.go: two-phase Load→LoadOrStore to avoid per-call
entry allocation on the hot path
* docs(webhooks): fix Sign() function doc to match actual key input
Function-level comment still referenced hex-decoded SecretHash after
the package-level doc was corrected. Align with actual caller usage
([]byte(rawSecret)).
* fix(webhooks): use WithoutCancel for worker execute DB updates
Terminal status writes in execute() ran through the worker main-loop
ctx, which is cancelled on graceful shutdown. If the outbound send
completed but the status update raced with shutdown, the row stayed
in 'running' and got re-delivered via reclaimStale. WithoutCancel
lets the DB write survive worker cancellation while preserving
propagated values (tenant ID, etc.).
* fix(webhooks): move tctx init before panic defer in worker execute
Panic recovery called updateRetry with raw ctx (no tenant ID), making
requireTenantID fail and the reset-to-retry DB write silently drop.
Row stayed 'running' until reclaimStale (~90s delay). Init tctx first
so defer closure captures tenant-scoped non-cancellable context.
* fix(webhooks): pass tenant-scoped tctx to invokeAgent in worker
execute() was passing the raw worker-loop ctx (no tenant ID) to
invokeAgent → router.Get → PGAgentStore.GetByID. GetByID reads
TenantIDFromContext which returned uuid.Nil, making every lookup
return 'agent not found'. Async LLM webhook calls silently failed
all retries. Pass tctx (already tenant-scoped + WithoutCancel) so
the router resolves the agent correctly.
* fix(tests): resolve integration test compile errors
- Remove duplicate contains() in mcp_grant_revoke_test.go (already
defined in tts_gemini_live_test.go)
- Update webhooks_admin_test.go RotateSecret call to match current
5-arg signature (newSecretHash, newPrefix, newEncryptedSecret)
* fix(webhooks): default nil scopes/ip_allowlist to empty slice in Create
PG columns are NOT NULL DEFAULT '{}'. Explicit NULL from pqStringArray(nil)
violated the constraint, breaking TestWebhookAdminCRUD/TenantIsolation.
Coerce nil slices to empty []string{} so the default applies at the DB layer.
* chore: trigger CI on digitopvn/goclaw fork
* ci: retrigger workflows
* fix(webhooks): renumber migrations to 000059-000061 for merge train
16 KiB
Multi-Tenant AI Agent Platform
Multi-agent AI gateway built in Go. 20+ LLM providers. 7 channels. Multi-tenant PostgreSQL.
Single binary. Production-tested. Agents that orchestrate for you.
Documentation • Quick Start • Twitter / X
🌐 Languages: 🇨🇳 简体中文 · 🇯🇵 日本語 · 🇰🇷 한국어 · 🇻🇳 Tiếng Việt · 🇵🇭 Tagalog · 🇪🇸 Español · 🇧🇷 Português · 🇮🇹 Italiano · 🇩🇪 Deutsch · 🇫🇷 Français · 🇸🇦 العربية · 🇮🇳 हिन्दी · 🇷🇺 Русский · 🇧🇩 বাংলা · 🇮🇱 עברית · 🇵🇱 Polski · 🇨🇿 Čeština · 🇳🇱 Nederlands · 🇹🇷 Türkçe · 🇺🇦 Українська · 🇮🇩 Bahasa Indonesia · 🇹🇭 ไทย · 🇵🇰 اردو · 🇷🇴 Română · 🇸🇪 Svenska · 🇬🇷 Ελληνικά · 🇭🇺 Magyar · 🇫🇮 Suomi · 🇩🇰 Dansk · 🇳🇴 Norsk
Core Features
- 8-Stage Agent Pipeline — context → history → prompt → think → act → observe → memory → summarize. Pluggable stages, always-on execution
- 4-Mode Prompt System — Full / Task / Minimal / None with section gating, cache boundary optimization, and per-session mode resolution
- 3-Tier Memory — Working (conversation) → Episodic (session summaries) → Semantic (knowledge graph). Progressive loading L0/L1/L2
- Knowledge Vault — Document registry with wikilinks, hybrid search (FTS + pgvector), filesystem sync
- Agent Teams & Orchestration — Shared task boards, inter-agent delegation (sync/async), 3 orchestration modes (auto/explicit/manual)
- Self-Evolution — Metrics → suggestions → auto-adapt with guardrails. Agents refine their own communication style
- Multi-Tenant PostgreSQL — Per-user workspaces, per-user context files, encrypted API keys (AES-256-GCM), RBAC, isolated sessions
- 20+ LLM Providers — Anthropic (native HTTP+SSE with prompt caching), OpenAI, OpenRouter, Groq, DeepSeek, Gemini, Mistral, xAI, MiniMax, DashScope, Claude CLI, Codex, ACP, and any OpenAI-compatible endpoint
- 7 Messaging Channels — Telegram, Discord, Slack, Zalo OA, Zalo Personal, Feishu/Lark, WhatsApp
- Production Security — 5-layer permission system, rate limiting, prompt injection detection, SSRF protection, AES-256-GCM encryption
- Single Binary — ~25 MB static Go binary, no Node.js runtime, <1s startup, runs on a $5 VPS
- Observability — Built-in LLM call tracing with spans and prompt cache metrics, optional OpenTelemetry OTLP export
Desktop Edition (GoClaw Lite)
A native desktop app for local AI agents — no Docker, no PostgreSQL, no infrastructure.
macOS:
curl -fsSL https://raw.githubusercontent.com/nextlevelbuilder/goclaw/main/scripts/install-lite.sh | bash
Windows (PowerShell):
irm https://raw.githubusercontent.com/nextlevelbuilder/goclaw/main/scripts/install-lite.ps1 | iex
What's Included
- Single native app (Wails v2 + React), ~30 MB
- SQLite database (zero setup)
- Chat with agents (streaming, tools, media, file attachments)
- Agent management (max 5), provider config, MCP servers, skills, cron
- Team tasks with Kanban board and real-time updates
- Auto-update from GitHub Releases
Lite vs Standard
| Feature | Lite (Desktop) | Standard (Server) |
|---|---|---|
| Agents | Max 5 | Unlimited |
| Teams | Max 1 (5 members) | Unlimited |
| Database | SQLite (local) | PostgreSQL |
| Memory | FTS5 text search | pgvector semantic |
| Channels | — | Telegram, Discord, Slack, Zalo, Feishu, WhatsApp |
| Knowledge Graph | — | Full |
| RBAC / Multi-tenant | — | Full |
| Auto-update | GitHub Releases | Docker / binary |
Building from Source
# Prerequisites: Go 1.26+, pnpm, Wails CLI (go install github.com/wailsapp/wails/v2/cmd/wails@latest)
make desktop-build # Build .app (macOS) or .exe (Windows)
make desktop-dmg VERSION=0.1.0 # Create .dmg installer (macOS only)
make desktop-dev # Dev mode with hot reload
Desktop Releases
Desktop uses independent versioning with lite-v* tags:
git tag lite-v0.1.0 && git push origin lite-v0.1.0
# → GitHub Actions builds macOS (.dmg + .tar.gz) + Windows (.zip)
# → Creates GitHub Release with all assets
Architecture
Quick Start
Prerequisites: Go 1.26+, PostgreSQL 18 with pgvector, Docker (optional)
From Source
git clone -b main https://github.com/nextlevelbuilder/goclaw.git && cd goclaw
make build
./goclaw onboard # Interactive setup wizard
source .env.local && ./goclaw
Note: The default branch is
dev(active development). Use-b mainto clone the stable release branch.
With Docker
# Generate .env with auto-generated secrets
chmod +x prepare-env.sh && ./prepare-env.sh
# Add at least one GOCLAW_*_API_KEY to .env, then:
make up
# Web Dashboard at http://localhost:18790 (built-in)
# Health check: curl http://localhost:18790/health
# Optional: separate nginx for custom SSL/reverse proxy
# make up WITH_WEB_NGINX=1 → Dashboard at http://localhost:3000
make up creates a Docker network, embeds the correct version from git tags, builds and starts all services, and runs database migrations automatically.
Common commands:
make up # Start all services (build + migrate)
make down # Stop all services
make logs # Tail logs (goclaw service)
make reset # Wipe volumes and rebuild from scratch
Optional services — enable with WITH_* flags:
| Flag | Service | What it does |
|---|---|---|
WITH_BROWSER=1 |
Headless Chrome | Enables browser tool for web scraping, screenshots, automation |
WITH_OTEL=1 |
Jaeger | OpenTelemetry tracing UI for debugging LLM calls and latency |
WITH_SANDBOX=1 |
Docker sandbox | Isolated container for running untrusted code from agents |
WITH_TAILSCALE=1 |
Tailscale | Expose gateway over Tailscale private network |
WITH_REDIS=1 |
Redis | Redis-backed caching layer |
Flags can be combined and work with all commands:
# Start with browser automation and tracing
make up WITH_BROWSER=1 WITH_OTEL=1
# Stop everything including optional services
make down WITH_BROWSER=1 WITH_OTEL=1
When GOCLAW_*_API_KEY environment variables are set, the gateway auto-onboards without interactive prompts — detects provider, runs migrations, and seeds default data.
Docker image variants:
Image Description latestBackend + embedded web UI + Python (recommended) latest-baseBackend API-only, no web UI, no runtimes latest-fullAll runtimes + skill dependencies pre-installed latest-otelLatest + OpenTelemetry tracing goclaw-webStandalone nginx + React SPA (for custom reverse proxy) For custom builds (Tailscale, Redis):
docker build --build-arg ENABLE_TSNET=true ...See the Deployment Guide for details.
Updating
Docker
docker compose pull && docker compose up -d
Binary (with embedded web UI)
goclaw update --apply # Downloads, verifies SHA256, swaps binary, restarts
Web Dashboard
Open About dialog → click Update Now (admin only). The update includes both backend and web dashboard when using the default latest image.
Multi-Agent Orchestration
Each agent runs with its own identity, tools, LLM provider, and context files. Three delegation modes — sync (wait), async (fire-and-forget), bidirectional — connected through explicit permission links with concurrency limits.
Details: Agent Teams docs
Knowledge Vault
Document registry with [[wikilinks]] for bidirectional linking. Hybrid search combines full-text (BM25) and semantic (pgvector) for precise retrieval. Filesystem sync keeps vault in sync with on-disk files.
Self-Evolution
Agents improve themselves through a 3-stage guardrailed pipeline: metrics collection → suggestion analysis → auto-adaptation. Can refine communication style and domain expertise (CAPABILITIES.md) — but never change identity, name, or core purpose.
Provider Adapters
20+ LLM providers unified through a single adapter interface. Capability-based routing, encrypted API keys (AES-256-GCM), extended thinking support per-provider, and prompt caching for Anthropic + OpenAI.
Event-Driven Architecture
Typed domain events power the consolidation pipeline — session summaries, knowledge graph extraction, and dreaming promotion all run asynchronously via worker pools with dedup and retry.
Built-in Tools
30+ tools across 8 categories:
| Category | Tools | Description |
|---|---|---|
| Filesystem | read_file, write_file, edit_file, list_files, search, glob |
File operations with virtual FS routing |
| Runtime | exec, browser |
Shell commands (approval workflow) + browser automation |
| Web | web_search, web_fetch |
Search (Brave, DuckDuckGo) + content extraction |
| Memory | memory_search, memory_get, knowledge_graph_search |
3-tier memory + KG traversal |
| Media | create_image, create_audio, create_video, read_*, tts |
Generation + analysis (multi-provider) |
| Skills | skill_search, use_skill, skill_manage |
BM25 + semantic hybrid search |
| Teams | team_tasks, spawn, delegate, message |
Task board + orchestration + messaging |
| Automation | cron, heartbeat, sessions_* |
Scheduling + session management |
Full tool reference at docs.goclaw.sh
Webhook API
Trigger agents or send channel messages from external systems without the gateway token.
# Bearer auth — sync LLM call
curl -X POST https://example.com/v1/webhooks/llm \
-H "Authorization: Bearer wh_..." \
-H "Content-Type: application/json" \
-d '{"input":"Summarize today metrics","mode":"sync"}'
# HMAC auth — sign with hmac_signing_key from create response
TS=$(date +%s); BODY='{"input":"hi","mode":"sync"}'
SIG=$(echo -n "${TS}.${BODY}" | openssl dgst -sha256 -mac HMAC \
-macopt "hexkey:${WEBHOOK_HMAC_KEY}" | awk '{print $2}')
curl -X POST https://example.com/v1/webhooks/llm \
-H "Content-Type: application/json" \
-H "X-Webhook-Id: ${WEBHOOK_ID}" \
-H "X-GoClaw-Signature: t=${TS},v1=${SIG}" \
-d "$BODY"
See docs/webhooks.md for the full reference: auth, async callbacks, retry schedule, HMAC examples, channel matrix.
Documentation
Full documentation at docs.goclaw.sh — or browse the source in goclaw-docs/
| Section | Topics |
|---|---|
| Getting Started | Installation, Quick Start, Configuration, Web Dashboard Tour |
| Core Concepts | Agent Loop, Sessions, Tools, Memory, Multi-Tenancy |
| Agents | Creating Agents, Context Files, Personality, Sharing & Access |
| Providers | Anthropic, OpenAI, OpenRouter, Gemini, DeepSeek, +15 more |
| Channels | Telegram, Discord, Slack, Feishu, Zalo, WhatsApp, WebSocket |
| Agent Teams | Teams, Task Board, Messaging, Delegation & Handoff |
| Advanced | Custom Tools, MCP, Skills, Cron, Sandbox, Hooks, RBAC |
| Deployment | Docker Compose, Database, Security, Observability, Tailscale |
| Reference | CLI Commands, REST API, WebSocket Protocol, Environment Variables |
Testing
go test ./... # Unit tests
go test -v ./tests/integration/ -timeout 120s # Integration tests (requires running gateway)
Project Status
See CHANGELOG.md for detailed feature status including what's been tested in production and what's still in progress.
Acknowledgments
GoClaw was originally inspired by the OpenClaw project architecture.
License
CC BY-NC 4.0 — Creative Commons Attribution-NonCommercial 4.0 International








