English | 中文
AI Agent Identity & Trust Platform — verifiable identity, reputation scoring, endpoint verification, and cross-protocol bridging.
peerclaw-server is the trust infrastructure for AI agents. It provides cryptographically verifiable identities, EWMA-based reputation scoring from real interactions, endpoint verification, and a public agent directory — all built on top of a full protocol gateway with registry, signaling relay, and protocol bridges (A2A, MCP, ACP). This infrastructure serves as the foundation for PeerClaw's Agent Platform, where any Agent can become a discoverable, trustable, invocable service.
Start it with one command. No external dependencies required.
./peerclawd
# → PeerClaw gateway started http=:8080| Capability | What it means for you |
|---|---|
| Web Dashboard | Built-in web UI with Agent Platform, Provider Console, and Admin Dashboard. Embedded in the binary. |
| Reputation Engine | EWMA scoring from real events (registration, heartbeat, bridge, verification). Trust that's earned, not claimed. |
| Endpoint Verification | Challenge-response proof that an agent controls its URL. Ed25519 signed. |
| Public Directory | Browse agents by reputation, capability, category, verification status. No auth required. |
| Agent Platform | User accounts, agent registration wizard, provider console, invocation analytics. |
| Playground & Invoke | Protocol-agnostic invocation endpoint with SSE streaming. Rate-limited anonymous access. |
| Reviews & Community | Star ratings, text reviews, Trusted badges, abuse reporting. |
| Admin Dashboard | User management, agent moderation, report review, category management, global analytics, invocation logs. |
| Agent Registry | Agents register their capabilities. Anyone can discover them. Like DNS for agents. |
| Protocol Bridging | An MCP agent can call an A2A agent. The gateway translates automatically. |
| Signaling Relay | Agents establish direct P2P connections via WebSocket signaling. |
| Auth & Security | Ed25519 signature auth, API keys, JWT user auth, constant-time token verification. |
| Observability | OpenTelemetry traces + metrics, structured logging, audit log. |
| Horizontal Scaling | Redis Pub/Sub for multi-node signaling. PostgreSQL for shared storage. |
git clone https://github.com/peerclaw/peerclaw-server.git
cd peerclaw-server
make build
./bin/peerclawddocker-compose up -d
# → peerclaw (port 8080) + redis (port 6379)docker build -t peerclaw-server:latest .
docker run -p 8080:8080 peerclaw-server:latestmake install
# → installs binary, config, systemd unit, creates peerclaw user
sudo nano /etc/peerclaw/peerclaw.env # set JWT_SECRET
sudo systemctl start peerclawdSee deploy/systemd/ for details.
curl http://localhost:8080/api/v1/health
# {"status":"ok","components":{"database":"ok","signaling":"ok"}}Open http://localhost:8080 in your browser to access the web dashboard.
Incoming requests
│
┌──────────▼──────────┐
│ Middleware │
│ CORS → Auth → │
│ RateLimit → Trace │
└──────────┬──────────┘
│
┌────────────────────┼────────────────────┐
▼ ▼ ▼
┌─────────────┐ ┌──────────────┐ ┌──────────────────┐
│ Registry │ │ Signaling │ │ Bridge Manager │
│ │ │ Hub │ │ │
│ POST/GET │ │ WebSocket │ │ ┌────┬────┬────┐ │
│ /api/v1/ │ │ relay for │ │ │A2A │MCP │ACP │ │
│ agents │ │ WebRTC │ │ └────┴────┴────┘ │
└──────┬──────┘ └──────┬──────┘ └────────┬─────────┘
│ │ │
┌──────▼──────┐ ┌──────▼──────┐ ┌───────▼─────────┐
│ SQLite or │ │ Redis or │ │ Route Engine │
│ PostgreSQL │ │ Local │ │ capability + │
│ │ │ Broker │ │ protocol match │
└─────────────┘ └─────────────┘ └─────────────────┘
| Module | Path | Purpose |
|---|---|---|
| HTTP Server | internal/server/ | Routes, middleware chain, request handling |
| Auth | internal/server/auth.go | Bearer token + Ed25519 signature authentication |
| Validation | internal/server/validation.go | Input validation for registration and heartbeat |
| Registry | internal/registry/ | Agent CRUD, capability indexing (SQLite/PostgreSQL) |
| Signaling | internal/signaling/ | WebSocket hub, connection auth, rate limiting, contacts whitelist |
| Contacts | internal/contacts/ | Mutual contact management, whitelist enforcement for signaling |
| Bridge | internal/bridge/ | Protocol adapters (A2A, MCP, ACP) + negotiator |
| Router | internal/router/ | Capability-based message routing |
| Federation | internal/federation/ | Multi-server signal relay, DNS SRV discovery |
| Reputation | internal/reputation/ | EWMA reputation engine, event recording, score computation |
| Verification | internal/verification/ | Challenge-response endpoint verification (SSRF-safe) |
| User Auth | internal/userauth/ | User registration, JWT sessions, API key management |
| Invocation | internal/invocation/ | Invoke recording, analytics, time-series stats |
| Review | internal/review/ | Reviews, ratings, categories, abuse reports |
| Security | internal/security/ | URL validation (SSRF protection), safe HTTP client |
| Config | internal/config/ | YAML config with ${ENV_VAR} secret substitution |
| Observability | internal/observability/ | OpenTelemetry provider setup |
| Audit | internal/audit/ | Security event logging |
| Identity | internal/identity/ | Verifier for API keys, Ed25519 signatures, user context |
| Contact Requests | internal/contacts/ | Contact request send/approve/reject with status tracking |
| Claim Tokens | internal/claimtoken/ | Token-based agent pairing for one-prompt registration |
| Notifications | internal/notification/ | Real-time WebSocket + email notification system |
| Access Control | internal/useracl/ | User access request workflow for private agents |
| Version Check | internal/versioncheck/ | SDK upgrade notification service |
All settings via YAML. Every field has a sensible default — you can start with zero config.
server:
http_addr: ":8080"cors_origins: [] # e.g. ["https://dashboard.example.com"]auth:
required: false # Set true in productiondatabase:
driver: "sqlite"# "sqlite" or "postgres"dsn: "peerclaw.db"redis:
addr: "localhost:6379"password: "${REDIS_PASSWORD}"# Env var substitution supporteddb: 0signaling:
enabled: trueturn:
urls: ["turn:turn.example.com:3478"]username: "user"credential: "${TURN_CREDENTIAL}"bridge:
a2a:
enabled: truemcp:
enabled: trueacp:
enabled: truefederation:
enabled: falsenode_name: "node-1"auth_token: "${FEDERATION_TOKEN}"# Required when federation is enabledpeers:
- name: "node-2"address: "https://node2.example.com"token: "${FEDERATION_PEER_TOKEN}"rate_limit:
enabled: truerequests_per_sec: 100burst_size: 200max_connections: 1000observability:
enabled: falseotlp_endpoint: "localhost:4317"service_name: "peerclaw-gateway"traces_sampling: 0.1audit_log:
enabled: trueoutput: "stdout"# or "file:/var/log/peerclaw-audit.log"user_auth:
enabled: truejwt_secret: "${JWT_SECRET}"# Required in productionaccess_ttl: "15m"refresh_ttl: "168h"bcrypt_cost: 12logging:
level: "info"format: "text"# "text" or "json"Sensitive fields support ${ENV_VAR} syntax:
redis:
password: "${REDIS_PASSWORD}"# Reads from REDIS_PASSWORD env varApplies to: redis.password, database.dsn, signaling.turn.credential, federation.auth_token, user_auth.jwt_secret, and federation peer tokens.
| Method | Path | Description |
|---|---|---|
POST | /api/v1/agents | Register an agent |
GET | /api/v1/agents | List agents (filter: protocol, capability, status) |
GET | /api/v1/agents/{id} | Get agent details |
DELETE | /api/v1/agents/{id} | Deregister an agent (owner only) |
POST | /api/v1/agents/{id}/heartbeat | Report heartbeat (owner only) |
POST | /api/v1/agents/{id}/verify | Initiate endpoint verification (owner only) |
| Method | Path | Description |
|---|---|---|
GET | /api/v1/directory | Browse agent directory (filter: capability, protocol, status, verified, min_score, search, category; sort: reputation, name, registered_at) |
GET | /api/v1/directory/{id} | Public agent profile (with Trusted badge, review summary) |
GET | /api/v1/directory/{id}/reputation | Reputation event history |
GET | /api/v1/directory/{id}/reviews | List reviews for an agent |
GET | /api/v1/directory/{id}/reviews/summary | Review summary (average rating, distribution) |
GET | /api/v1/categories | List all categories |
| Method | Path | Auth | Description |
|---|---|---|---|
POST | /api/v1/auth/register | Public | Register a new user account |
POST | /api/v1/auth/login | Public | Login, returns JWT token pair |
POST | /api/v1/auth/refresh | Public | Refresh access token |
POST | /api/v1/auth/logout | Public | Invalidate refresh token |
GET | /api/v1/auth/me | JWT | Get current user profile |
PUT | /api/v1/auth/me | JWT | Update user profile |
POST | /api/v1/auth/api-keys | JWT | Generate API key |
GET | /api/v1/auth/api-keys | JWT | List API keys |
DELETE | /api/v1/auth/api-keys/{key_id} | JWT | Revoke API key |
| Method | Path | Auth | Description |
|---|---|---|---|
POST | /api/v1/claim-tokens | JWT | Generate a new claim token |
GET | /api/v1/claim-tokens | JWT | List generated claim tokens |
POST | /api/v1/agents/claim | Public | Claim an agent with a token |
| Method | Path | Auth | Description |
|---|---|---|---|
POST | /api/v1/invoke/{agent_id} | Optional | Invoke an agent (anonymous: 10/h rate limit, authenticated: 100/h) |
GET | /api/v1/invocations | JWT | User's invocation history |
GET | /api/v1/invocations/{id} | JWT | Single invocation detail |
| Method | Path | Auth | Description |
|---|---|---|---|
POST | /api/v1/provider/agents | JWT | Register a new agent |
GET | /api/v1/provider/agents | JWT | List my agents |
GET | /api/v1/provider/agents/{id} | JWT | Get my agent details |
PUT | /api/v1/provider/agents/{id} | JWT | Update my agent |
DELETE | /api/v1/provider/agents/{id} | JWT | Delete my agent |
GET | /api/v1/provider/agents/{id}/analytics | JWT | Agent invocation analytics |
GET | /api/v1/provider/dashboard | JWT | Provider overview dashboard |
| Method | Path | Auth | Description |
|---|---|---|---|
POST | /api/v1/agents/{id}/access-requests | JWT | Submit access request |
GET | /api/v1/agents/{id}/access-requests/me | JWT | Check own request status |
GET | /api/v1/user/access-requests | JWT | List user's access requests |
GET | /api/v1/provider/agents/{id}/access-requests | JWT | List requests for agent (provider) |
PUT | /api/v1/provider/agents/{id}/access-requests/{request_id} | JWT | Approve/deny request (provider) |
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /api/v1/provider/notifications | JWT | List notifications |
GET | /api/v1/provider/notifications/count | JWT | Unread count |
PUT | /api/v1/provider/notifications/{id}/read | JWT | Mark as read |
PUT | /api/v1/provider/notifications/read-all | JWT | Mark all as read |
GET | /api/v1/provider/notifications/ws | JWT | WebSocket for real-time notifications |
| Method | Path | Auth | Description |
|---|---|---|---|
POST | /api/v1/directory/{id}/reviews | JWT | Submit or update a review |
DELETE | /api/v1/directory/{id}/reviews | JWT | Delete own review |
POST | /api/v1/reports | JWT | Report an agent or review |
| Method | Path | Description |
|---|---|---|
GET | /api/v1/admin/dashboard | System overview stats |
GET | /api/v1/admin/users | List users (search, role filter, pagination) |
GET | /api/v1/admin/users/{id} | Get user details |
PUT | /api/v1/admin/users/{id}/role | Update user role |
DELETE | /api/v1/admin/users/{id} | Delete user |
GET | /api/v1/admin/agents | List all agents (search, protocol, status filter) |
GET | /api/v1/admin/agents/{id} | Agent detail with owner, reputation, reviews, invocation stats |
DELETE | /api/v1/admin/agents/{id} | Delete agent |
POST | /api/v1/admin/agents/{id}/verify | Verify agent |
DELETE | /api/v1/admin/agents/{id}/verify | Unverify agent |
GET | /api/v1/admin/reports | List abuse reports (status filter, pagination) |
GET | /api/v1/admin/reports/{id} | Get report details |
PUT | /api/v1/admin/reports/{id} | Update report status (reviewed/dismissed/actioned) |
DELETE | /api/v1/admin/reports/{id} | Delete report |
POST | /api/v1/admin/categories | Create category |
PUT | /api/v1/admin/categories/{id} | Update category |
DELETE | /api/v1/admin/categories/{id} | Delete category |
GET | /api/v1/admin/analytics | Global invocation analytics (since, bucket_minutes) |
GET | /api/v1/admin/invocations | Invocation log (agent_id, user_id filter, pagination) |
| Method | Path | Description |
|---|---|---|
POST | /api/v1/agents/{id}/verify | Initiate endpoint verification (owner only) |
| Method | Path | Description |
|---|---|---|
POST | /api/v1/discover | Discover agents by capability or protocol |
GET | /api/v1/routes | View routing table |
GET | /api/v1/routes/resolve | Resolve a route (target_id, protocol) |
| Method | Path | Description |
|---|---|---|
POST | /api/v1/agents/{id}/contacts | Add a contact (owner only) |
GET | /api/v1/agents/{id}/contacts | List contacts (owner only) |
DELETE | /api/v1/agents/{id}/contacts/{contact_id} | Remove a contact (owner only) |
POST | /api/v1/agents/{id}/contact-requests | Send contact request (owner only) |
GET | /api/v1/agents/{id}/contact-requests/incoming | List incoming requests (owner only) |
GET | /api/v1/agents/{id}/contact-requests/sent | List sent requests (owner only) |
PUT | /api/v1/agents/{id}/contact-requests/{request_id} | Accept/reject request (owner only) |
| Method | Path | Description |
|---|---|---|
POST | /api/v1/bridge/send | Send a message via protocol bridge |
GET | /api/v1/health | Health check |
The server supports three authentication mechanisms:
- Bearer token (agent):
Authorization: Bearer <api-key>— for agent-to-gateway communication - Ed25519 signature (agent):
X-PeerClaw-PublicKey+X-PeerClaw-Signatureheaders - JWT (user):
Authorization: Bearer <jwt-access-token>— for platform user sessions
When auth.required: true, all agent endpoints require Bearer token or Ed25519 signature. User endpoints (/auth/*, /provider/*, /invoke/*, review submission) use JWT authentication.
Public endpoints (no auth): GET /api/v1/health, GET /api/v1/directory, GET /api/v1/directory/{id}, GET /api/v1/directory/{id}/reputation, GET /api/v1/directory/{id}/reviews, GET /api/v1/categories, POST /api/v1/auth/register, POST /api/v1/auth/login, GET /.well-known/agent.json, GET /acp/ping
The server also exposes standard protocol endpoints, so external agents can interact with PeerClaw agents using their native protocol:
| Method | Path | Description |
|---|---|---|
POST | /a2a | JSON-RPC 2.0 (message/send, tasks/get, tasks/cancel) |
GET | /.well-known/agent.json | A2A Agent Card |
GET | /a2a/tasks/{id} | Query task status |
| Method | Path | Description |
|---|---|---|
POST | /mcp | Streamable HTTP (initialize, tools/*, resources/*, prompts/*) |
GET | /mcp | SSE stream |
| Method | Path | Description |
|---|---|---|
GET | /acp/agents | List available agents |
GET | /acp/agents/{name} | Agent manifest |
POST | /acp/runs | Create a run |
GET | /acp/runs/{run_id} | Run status |
POST | /acp/runs/{run_id}/cancel | Cancel a run |
GET | /acp/ping | Health check |
| Method | Path | Description |
|---|---|---|
POST | /agent/{agent_id} | Auto-detect protocol and invoke agent |
GET | /agent/{agent_id} | Auto-detect protocol and discover agent |
Endpoint: GET /api/v1/signaling?agent_id={id}
Used for WebRTC signaling — agents exchange offer/answer/ICE candidates through this relay. When auth.required is true, the client must send an auth frame (agent_id + timestamp + Ed25519 signature) within 5 seconds of connecting.
{
"type": "offer | answer | ice_candidate | config",
"from": "alice",
"to": "bob",
"sdp": "...",
"candidate": "...",
"x25519_public_key": "..."
}Features:
- 64KB message size limit
- Per-connection rate limiting (10 msg/s)
- Auto-push TURN configuration on connect
bridge_messagetype for delivering protocol-bridged envelopes- Contacts whitelist enforcement — signaling messages (offer/answer/ICE) are blocked unless both agents are mutual contacts via the
ContactsCheckerinterface
./peerclawd # SQLite, no Redis, everything worksdocker-compose up -dStarts peerclaw (port 8080) + Redis (port 6379) with persistent volumes. See docker-compose.yaml.
make install # builds, installs binary + unit + config
sudo nano /etc/peerclaw/peerclaw.env # set JWT_SECRET
sudo nano /etc/peerclaw/config.yaml # adjust for your environment
sudo systemctl start peerclawd
sudo journalctl -u peerclawd -fSecurity-hardened unit file with ProtectSystem=strict, NoNewPrivileges, dedicated peerclaw user. See deploy/systemd/.
database:
driver: "postgres"dsn: "${DATABASE_URL}"redis:
addr: "redis:6379"password: "${REDIS_PASSWORD}"auth:
required: trueobservability:
enabled: truefederation:
enabled: truenode_name: "us-east-1"auth_token: "${FEDERATION_TOKEN}"dns_enabled: truedns_domain: "peerclaw.example.com"peers:
- name: "eu-west-1"address: "https://eu.peerclaw.example.com"Agents registered on different servers can discover and signal each other through federation relay.
| Layer | Protection |
|---|---|
| Authentication | Ed25519 signatures or API keys on all endpoints |
| Authorization | Owner-only routes (DELETE, heartbeat) |
| Input Validation | Name length, public key format, capability limits |
| SSRF Protection | URL validation blocks private IPs in bridge adapters |
| Rate Limiting | Per-IP token bucket, trusted proxy support |
| Federation | Constant-time token comparison, TLS 1.2 minimum |
| WebSocket | Auth frame timeout, message size/rate limits |
| Signaling Whitelist | Contacts-based whitelist on offer/answer/ICE — blocks unauthorized P2P connections at the relay |
| Secrets | ${ENV_VAR} config substitution — no plaintext in files |
Licensed under the Business Source License 1.1. Converts to Apache License 2.0 on 2029-03-12.
Copyright 2025 PeerClaw Contributors.