Files
goclaw/docs/04-gateway-protocol.md
T

20 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, config.permissions.*, 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

Agent Evolution (v3)

Method Description
agent.evolution.suggestions Get evolution suggestions for an agent (requires metrics enabled)
agent.evolution.apply Apply a suggested evolution to an agent configuration
agent.evolution.rollback Roll back applied evolution with quality guardrails

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
config.permissions.list List agent config permission rules
config.permissions.check Preview effective permission for an agent, scope, config type, and user
config.permissions.grant Add or update an agent config permission rule
config.permissions.revoke Remove an agent config permission rule

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 (configurable, default 20 MB, max 500 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

Module Path Purpose
Gateway core internal/gateway/ WS server, HTTP mux, method router, rate limiter, client lifecycle
RPC handlers internal/gateway/methods/ All WS RPC handlers: chat, agents, sessions, config, skills, cron, teams, channels, pairing, exec approval, usage, API keys
HTTP handlers internal/http/ All REST endpoints: /v1/chat/completions, /v1/agents, /v1/skills, /v1/traces, /v1/mcp, auth, OAuth, summoner
Protocol types pkg/protocol/ Frame types, RPC method constants, event names, error codes

Use grep or your editor's symbol search for specific files.