Files
goclaw/docs/04-gateway-protocol.md
Viet Tran 037d18f711 docs: comprehensive audit and update of all documentation (#231)
* feat(ui): improve kanban UX, fix dialog scroll, remove delegation page

- Kanban: reorder columns (blocked after pending), show blocked-by info
  on cards, clickable blocker links in task detail, framer-motion card
  animation between columns
- Dialogs: standardize scroll pattern across all modals — header fixed,
  scrollbar flush with outer edge via negative margin trick
- Remove delegation page, types, events, i18n, routes, and all references
- Fix activity_logs NULL jsonb scan error (COALESCE)
- Board header: show text labels on action buttons (desktop)

* docs: comprehensive audit and update of all documentation

- Update Go 1.25 → 1.26, PostgreSQL 15+ → 18 across all docs
- Add 10 missing internal modules to CLAUDE.md project structure
- Expand provider docs from 2 to 6 packages (Anthropic, OpenAI, DashScope, Claude CLI, ACP, Codex)
- Add 8 missing store interfaces to data model docs (22 total)
- Update bootstrap files from 7 to 13 templates
- Expand tool inventory from ~35 to 60+ tools with media/KG/credential categories
- Fix Team Task Board: add blocked status, 3 missing actions, V2 versioning, delegate restrictions
- Remove all references to removed features: handoff, delegate_search, evaluate_loop, agent_links
- Fix lane defaults (2/4/1 → 30/50/100/30), ghost file references, models.list → providers.models
- Add SecureCLI, snapshot worker, cost calculation, pairing security docs
- Comprehensive changelog catch-up
- Trim docs/03-tools-system.md to 800-line limit
2026-03-16 22:51:57 +07:00

23 KiB

04 - Gateway and Protocol

The gateway is the central component of GoClaw, serving both WebSocket RPC (Protocol v3) and HTTP REST API on a single port. It handles authentication, role-based access control, rate limiting, and method dispatch for all client interactions.


1. WebSocket Lifecycle

sequenceDiagram
    participant C as Client
    participant S as Server

    C->>S: HTTP GET /ws
    S-->>C: 101 Switching Protocols

    Note over S: Create Client, register,<br/>subscribe to event bus

    C->>S: req: connect {token, user_id}
    S-->>C: res: {protocol: 3, role, user_id}

    loop RPC Communication
        C->>S: req: chat.send {message, agentId, ...}
        S-->>C: event: agent {run.started}
        S-->>C: event: chat {chunk} (repeated)
        S-->>C: event: agent {tool.call}
        S-->>C: event: agent {tool.result}
        S-->>C: res: {content, usage}
    end

    Note over C,S: Ping/Pong every 30s

    C->>S: close
    Note over S: Unregister, cleanup,<br/>unsubscribe from event bus

Connection Parameters

Parameter Value Description
Read limit 512 KB Auto-close connection on exceed
Send buffer 256 capacity Drop messages when full
Read deadline 60s Reset on each message or pong
Write deadline 10s Per-write timeout
Ping interval 30s Server-initiated keepalive

2. Protocol v3 Frame Types

Type Direction Purpose
req Client to Server Invoke an RPC method
res Server to Client Response matching request by id
event Server to Client Push events (streaming chunks, agent status, etc.)

The first request from a client must be connect. Any other method sent before authentication results in an UNAUTHORIZED error.

Request Frame Structure

  • type: always "req"
  • id: unique request ID (client-generated)
  • method: RPC method name
  • params: method-specific parameters (JSON)

Response Frame Structure

  • type: always "res"
  • id: matches the request ID
  • ok: boolean success indicator
  • payload: response data (when ok is true)
  • error: error shape with code, message, details, retryable, retryAfterMs (when ok is false)

Event Frame Structure

  • type: always "event"
  • event: event name (e.g., chat, agent, status)
  • payload: event data
  • seq: ordering sequence number
  • stateVersion: version counters for optimistic state sync

3. Authentication and RBAC

Connect Handshake

flowchart TD
    FIRST{"First frame = connect?"} -->|No| REJECT["UNAUTHORIZED<br/>'first request must be connect'"]
    FIRST -->|Yes| TOKEN{"Token match?"}
    TOKEN -->|"Config token matches"| ADMIN["Role: admin"]
    TOKEN -->|"No config token set"| OPER["Role: operator"]
    TOKEN -->|"Wrong or missing token"| VIEW["Role: viewer"]

Token comparison uses crypto/subtle.ConstantTimeCompare to prevent timing attacks.

The user_id in the connect parameters is required for per-user session scoping and context file routing. GoClaw uses the Identity Propagation pattern — it trusts the upstream service to provide accurate user identity. The user_id is opaque (VARCHAR 255); multi-tenant deployments use the compound format tenant.{tenantId}.user.{userId}. See 00-architecture-overview.md Section 5 for details.

Three Roles

flowchart LR
    V["viewer (level 1)<br/>Read only"] --> O["operator (level 2)<br/>Read + Write"]
    O --> A["admin (level 3)<br/>Full control"]

Method Permissions

Role Accessible Methods
viewer agents.list, config.get, sessions.list, sessions.preview, health, status, providers.models, skills.list, skills.get, channels.list, channels.status, cron.list, cron.status, cron.runs, usage.get, usage.summary
operator All viewer methods plus: chat.send, chat.abort, chat.history, chat.inject, sessions.delete, sessions.reset, sessions.patch, cron.create, cron.update, cron.delete, cron.toggle, cron.run, skills.update, send, exec.approval.list, exec.approval.approve, exec.approval.deny, device.pair.request, device.pair.list
admin All operator methods plus: config.apply, config.patch, agents.create, agents.update, agents.delete, agents.files.*, teams.*, channels.toggle, device.pair.approve, device.pair.revoke

4. Request Handling Pipeline

flowchart TD
    REQ["Client sends RequestFrame"] --> PARSE["Parse frame type"]
    PARSE --> AUTH{"Authenticated?"}
    AUTH -->|"No and method is not connect"| UNAUTH["UNAUTHORIZED"]
    AUTH -->|"Yes or method is connect"| FIND{"Handler found?"}
    FIND -->|No| INVALID["INVALID_REQUEST<br/>'unknown method'"]
    FIND -->|Yes| PERM{"Permission check<br/>(skip for connect, health)"}
    PERM -->|Insufficient role| DENIED["UNAUTHORIZED<br/>'permission denied'"]
    PERM -->|OK| EXEC["Execute handler(ctx, client, req)"]
    EXEC --> RES["Send ResponseFrame"]

5. RPC Methods

System

Method Description
connect Authentication handshake (must be first request)
health Health check
status Gateway status (connected clients, agents, channels)
providers.models List available models from all providers

Chat

Method Description
chat.send Send a message to an agent, receive streaming response
chat.history Get conversation history for a session
chat.abort Abort a running agent loop
chat.inject Inject a system message into a session

Agents

Method Description
agent Get details for a specific agent
agent.wait Wait for an agent to become available
agent.identity.get Get agent identity (name, description)
agents.list List all accessible agents
agents.create Create a new agent
agents.update Update agent configuration
agents.delete Soft-delete an agent
agents.files.list List agent context files
agents.files.get Read a context file
agents.files.set Write a context file

Sessions

Method Description
sessions.list List all sessions
sessions.preview Preview session content
sessions.patch Update session metadata
sessions.delete Delete a session
sessions.reset Reset session history

Config

Method Description
config.get Get current configuration (secrets redacted)
config.apply Replace entire configuration
config.patch Partial configuration update
config.schema Get configuration JSON schema

Skills

Method Description
skills.list List all skills
skills.get Get skill details
skills.update Update skill content

Cron

Method Description
cron.list List scheduled jobs
cron.create Create a new cron job
cron.update Update a cron job
cron.delete Delete a cron job
cron.toggle Enable/disable a cron job
cron.status Get cron system status
cron.run Manually trigger a cron job
cron.runs List recent run logs

Channels

Method Description
channels.list List enabled channels
channels.status Get channel running status
channels.toggle Enable/disable a channel (admin only)

Pairing

Method Description
device.pair.request Request a pairing code
device.pair.approve Approve a pairing request
device.pair.list List paired devices
device.pair.revoke Revoke a paired device
browser.pairing.status Poll browser pairing approval status

Exec Approval

Method Description
exec.approval.list List pending exec approval requests
exec.approval.approve Approve an exec request
exec.approval.deny Deny an exec request

Usage and Send

Method Description
usage.get Get token usage for a session
usage.summary Get aggregated usage summary
send Send a direct message to a channel

TTS (Text-to-Speech)

Method Description
tts.status Get TTS system status
tts.enable Enable TTS
tts.disable Disable TTS
tts.convert Convert text to speech
tts.setProvider Set active TTS provider
tts.providers List available TTS providers

Browser

Method Description
browser.act Execute browser action (navigate, click, type)
browser.snapshot Get DOM snapshot
browser.screenshot Take screenshot

Teams

Method Description
teams.list List agent teams
teams.create Create a team (lead + members)
teams.get Get team details with members
teams.delete Delete a team
teams.update Update team configuration
teams.tasks.list List team tasks
teams.tasks.get Get task details
teams.tasks.create Create a new task
teams.tasks.delete Delete a task
teams.tasks.claim Claim a task (mark as in-progress)
teams.tasks.assign Assign task to member
teams.tasks.approve Approve completed task
teams.tasks.reject Reject task submission
teams.tasks.comment Add comment to task
teams.tasks.comments Get task comments
teams.tasks.events Get task event history
teams.members.add Add member to team
teams.members.remove Remove member from team
teams.workspace.list List team workspace files
teams.workspace.read Read workspace file content
teams.workspace.delete Delete workspace file
teams.events.list List team event history
teams.known_users Get list of known users for team
teams.scopes Get team member scopes

Delegations

Method Description
delegations.list List delegation history (result truncated to 500 runes)
delegations.get Get delegation detail (result truncated to 8000 runes)

Channel Instances

Method Description
channels.instances.list List channel instances
channels.instances.get Get channel instance details
channels.instances.create Create a new channel instance
channels.instances.update Update channel instance config
channels.instances.delete Delete a channel instance

API Keys

Method Description
api_keys.list List API keys
api_keys.create Create a new API key
api_keys.revoke Revoke an API key

Usage and Quotas

Method Description
quota.usage Get quota usage information

Other

Method Description
logs.tail Tail gateway logs

6. HTTP API

Authentication

  • Authorization: Bearer <token> -- timing-safe comparison via crypto/subtle.ConstantTimeCompare
  • No token configured: all requests allowed
  • X-GoClaw-User-Id: required for per-user scoping
  • X-GoClaw-Agent-Id: specify target agent for the request

Endpoints

POST /v1/chat/completions (OpenAI-compatible)

flowchart TD
    REQ["HTTP Request"] --> AUTH["Bearer token check"]
    AUTH --> RL["Rate limit check"]
    RL --> BODY["MaxBytesReader (1 MB)"]
    BODY --> AGENT["Resolve agent<br/>(model prefix / header / default)"]
    AGENT --> RUN["agent.Run()"]
    RUN --> RESP{"Streaming?"}
    RESP -->|Yes| SSE["SSE: text/event-stream<br/>data: chunks...<br/>data: [DONE]"]
    RESP -->|No| JSON["JSON response<br/>(OpenAI format)"]

Agent resolution priority: model field with goclaw: or agent: prefix, then X-GoClaw-Agent-Id header, then "default".

POST /v1/responses (OpenResponses Protocol)

Same agent resolution and execution flow, different response format (response.started, response.delta, response.done).

POST /v1/tools/invoke

Direct tool invocation without the agent loop. Supports dryRun: true to return tool schema only.

GET /health

Returns {"status":"ok","protocol":3}.

CRUD Endpoints

All CRUD endpoints require Authorization: Bearer <token> and X-GoClaw-User-Id header for per-user scoping.

Agents (/v1/agents):

Method Path Description
GET /v1/agents List accessible agents (filtered by user shares)
POST /v1/agents Create a new agent
GET /v1/agents/{id} Get agent details
PUT /v1/agents/{id} Update agent configuration
DELETE /v1/agents/{id} Soft-delete an agent

Custom Tools (/v1/tools/custom):

Method Path Description
GET /v1/tools/custom List tools (optional ?agent_id= filter)
POST /v1/tools/custom Create a custom tool
GET /v1/tools/custom/{id} Get tool details
PUT /v1/tools/custom/{id} Update a tool
DELETE /v1/tools/custom/{id} Delete a tool

MCP Servers (/v1/mcp):

Method Path Description
GET /v1/mcp/servers List registered MCP servers
POST /v1/mcp/servers Register a new MCP server
GET /v1/mcp/servers/{id} Get server details
PUT /v1/mcp/servers/{id} Update server config
DELETE /v1/mcp/servers/{id} Remove MCP server
POST /v1/mcp/servers/{id}/grants/agent Grant access to an agent
DELETE /v1/mcp/servers/{id}/grants/agent/{agentID} Revoke agent access
GET /v1/mcp/grants/agent/{agentID} List agent's MCP grants
POST /v1/mcp/servers/{id}/grants/user Grant access to a user
DELETE /v1/mcp/servers/{id}/grants/user/{userID} Revoke user access
POST /v1/mcp/requests Request access (user self-service)
GET /v1/mcp/requests List pending access requests
POST /v1/mcp/requests/{id}/review Approve or reject a request

Agent Sharing (/v1/agents/{id}/sharing):

Method Path Description
GET /v1/agents/{id}/sharing List shares for an agent
POST /v1/agents/{id}/sharing Share agent with a user
DELETE /v1/agents/{id}/sharing/{userID} Revoke user access

Delegations (/v1/delegations):

Method Path Description
GET /v1/delegations List delegation history (full records, paginated)
GET /v1/delegations/{id} Get delegation detail

Skills (/v1/skills):

Method Path Description
GET /v1/skills List skills
POST /v1/skills/upload Upload skill ZIP (max 20 MB)
DELETE /v1/skills/{id} Delete a skill

Traces (/v1/traces):

Method Path Description
GET /v1/traces List traces (filter by agent_id, user_id, status, date range)
GET /v1/traces/{id} Get trace details with all spans

Channel Instances (/v1/channel-instances):

Method Path Description
GET /v1/channel-instances List channel instances
POST /v1/channel-instances Create a new channel instance
GET /v1/channel-instances/{id} Get channel instance details
PUT /v1/channel-instances/{id} Update channel instance config
DELETE /v1/channel-instances/{id} Delete a channel instance

API Keys (/v1/api-keys):

Method Path Description
GET /v1/api-keys List API keys
POST /v1/api-keys Create a new API key
DELETE /v1/api-keys/{id} Revoke an API key

Providers & Models (/v1/providers):

Method Path Description
GET /v1/providers List LLM providers
POST /v1/providers Create a new provider
GET /v1/providers/{id} Get provider details
PUT /v1/providers/{id} Update provider config
DELETE /v1/providers/{id} Delete a provider

Memory (/v1/memory):

Method Path Description
GET /v1/memory Get memory entries
POST /v1/memory Create memory entry
DELETE /v1/memory/{id} Delete memory entry

Knowledge Graph (/v1/kg):

Method Path Description
GET /v1/kg/entities List entities
POST /v1/kg/entities Create entity
GET /v1/kg/relations List relationships
POST /v1/kg/relations Create relationship

Files & Storage (/v1/files, /v1/storage):

Method Path Description
GET /v1/files List workspace files
GET /v1/files/{path} Serve file content
DELETE /v1/storage/{path} Delete workspace file

Media (/v1/media):

Method Path Description
POST /v1/media/upload Upload media file
GET /v1/media/{id} Serve media file

Activity & Usage (/v1/activity, /v1/usage):

Method Path Description
GET /v1/activity List activity audit logs
GET /v1/usage Get usage metrics
GET /v1/usage/summary Get aggregated usage summary

OAuth & Docs (/oauth, /docs):

Method Path Description
GET,POST /oauth/* OAuth authentication endpoints
GET /docs/openapi.json OpenAPI specification
GET /docs/swagger-ui/ Swagger UI

MCP Bridge (/mcp/bridge):

Method Path Description
POST /mcp/bridge MCP server bridge (Claude CLI tools)

7. Rate Limiting

Token bucket rate limiting per user or IP address. Configured via gateway.rate_limit_rpm (0 = disabled, > 0 = enabled).

flowchart TD
    REQ["Request"] --> CHECK{"rate_limit_rpm > 0?"}
    CHECK -->|No| PASS["Allow all requests"]
    CHECK -->|Yes| BUCKET{"Token available<br/>for this key?"}
    BUCKET -->|Yes| ALLOW["Allow + consume token"]
    BUCKET -->|No| REJECT["WS: INVALID_REQUEST<br/>HTTP: 429 + Retry-After: 60"]
Aspect WebSocket HTTP
Rate key client.UserID() fallback client.ID() RemoteAddr fallback "token:" + bearer
On limit INVALID_REQUEST "rate limit exceeded" HTTP 429
Burst 5 requests 5 requests
Cleanup Every 5 min, entries inactive > 10 min Same

8. Error Codes

Code Description
UNAUTHORIZED Authentication failed or insufficient role
INVALID_REQUEST Missing or invalid fields in the request
NOT_FOUND Requested resource does not exist
ALREADY_EXISTS Resource already exists (conflict)
UNAVAILABLE Service temporarily unavailable
RESOURCE_EXHAUSTED Rate limit exceeded
FAILED_PRECONDITION Operation prerequisites not met
AGENT_TIMEOUT Agent run exceeded time limit
INTERNAL Unexpected server error

Error responses include retryable (boolean) and retryAfterMs (integer) fields to guide client retry behavior.


File Reference

File Purpose
internal/gateway/server.go Server: WebSocket upgrade, HTTP mux, CORS check, client lifecycle
internal/gateway/client.go Client: connection management, read/write pumps, send buffer
internal/gateway/router.go MethodRouter: handler registration, permission-checked dispatch
internal/gateway/ratelimit.go RateLimiter: token bucket per key, cleanup loop
internal/gateway/methods/chat.go chat.send, chat.history, chat.abort, chat.inject handlers
internal/gateway/methods/agents.go agents.list, agents.create/update/delete, agents.files.* handlers
internal/gateway/methods/sessions.go sessions.list/preview/patch/delete/reset handlers
internal/gateway/methods/config.go config.get/apply/patch/schema handlers
internal/gateway/methods/skills.go skills.list/get/update handlers
internal/gateway/methods/cron.go cron.list/create/update/delete/toggle/run/runs handlers
internal/gateway/methods/teams.go teams.* handlers + auto-linking teammates
internal/gateway/methods/teams_workspace.go teams.workspace.* handlers (file management)
internal/gateway/methods/delegations.go delegations.list/get handlers
internal/gateway/methods/channels.go channels.list/status/toggle handlers
internal/gateway/methods/channel_instances.go channels.instances.* handlers (CRUD)
internal/gateway/methods/pairing.go device.pair.* and browser.pairing.* handlers
internal/gateway/methods/exec_approval.go exec.approval.* handlers
internal/gateway/methods/usage.go usage.get/summary handlers
internal/gateway/methods/api_keys.go api_keys.list/create/revoke handlers
internal/gateway/methods/send.go send handler (direct message to channel)
internal/http/chat_completions.go POST /v1/chat/completions (OpenAI-compatible)
internal/http/responses.go POST /v1/responses (OpenResponses protocol)
internal/http/tools_invoke.go POST /v1/tools/invoke (direct tool execution)
internal/http/agents.go Agent CRUD HTTP handlers (/v1/agents, /v1/agents/{id}/sharing)
internal/http/skills.go Skills HTTP handlers (/v1/skills, upload, dependencies)
internal/http/traces.go Traces HTTP handlers (/v1/traces)
internal/http/delegations.go Delegation history HTTP handlers (/v1/delegations)
internal/http/channel_instances.go Channel instance CRUD handlers (/v1/channel-instances)
internal/http/providers.go LLM provider CRUD handlers (/v1/providers)
internal/http/memory.go Memory management handlers (/v1/memory)
internal/http/knowledge_graph.go Knowledge graph handlers (/v1/kg)
internal/http/files.go Workspace file serving handlers (/v1/files)
internal/http/storage.go Storage file CRUD handlers (/v1/storage)
internal/http/media_upload.go Media upload handlers (/v1/media/upload)
internal/http/media_serve.go Media serving handlers (/v1/media/{id})
internal/http/activity.go Activity audit log handlers (/v1/activity)
internal/http/usage.go Usage analytics handlers (/v1/usage)
internal/http/api_keys.go API key management handlers (/v1/api-keys)
internal/http/custom_tools.go Custom tool CRUD handlers (/v1/tools/custom)
internal/http/mcp.go MCP server management handlers (/v1/mcp)
internal/http/summoner.go LLM-powered agent setup (XML parsing, context file generation)
internal/http/auth.go Bearer token authentication, timing-safe comparison
internal/http/oauth.go OAuth authentication endpoints (/oauth)
internal/http/docs.go OpenAPI documentation handlers (/docs)
internal/mcp/bridge.go MCP bridge for Claude CLI integration (/mcp/bridge)
internal/permissions/policy.go PolicyEngine: role hierarchy, method-to-role mapping
pkg/protocol/frames.go Frame types: RequestFrame, ResponseFrame, EventFrame, ErrorShape
pkg/protocol/methods.go RPC method name constants (Phase 1-3)
pkg/protocol/events.go WebSocket event names and event subtypes
pkg/protocol/errors.go Error code constants and error factories