# Agent Trust Map
When AI agents interact through tool calls, SolonGate tracks which agent made each call, computes a trust score per agent, and visualizes trust relationships in an interactive graph. Available in the dashboard under Trust Map.
Why Trust Map? When multiple AI agents (Claude Code, Gemini CLI, custom bots) work on the same project, you need visibility into who does what. Which agent triggers the most denials? Which agents share tools? Is a new agent behaving suspiciously?
How data is collected: SolonGate uses hooks to capture every tool call. When you run npx @solongate/proxy@latest init --all, it installs two hooks in your project:
- guard.mjs (PreToolUse) — runs before every tool call, enforces policies, logs ALLOW/DENY decisions
- audit.mjs (PostToolUse) — runs after every tool call, logs execution results
These hooks work with Claude Code, Gemini CLI, and other AI tools — no manual server setup needed. Agent identity is auto-detected from the AI client.
How It Works
The trust map works in 4 steps, from identity capture to visualization:
Agent Identity Capture
CLI flag, HTTP headers, or client auto-detection
Audit Log with Agent ID
Every tool call tagged with agent identity
Trust Score Computation
Based on allow/deny ratios and PI detections
Dashboard Visualization
Interactive force-directed graph
Agent Identity Sources
SolonGate captures agent identity from 3 sources, in priority order. The first available source is used:
Client Detection (Automatic)
Auto-detected from client handshake — Claude Code, Gemini CLI, etc.
CLI Flag (Custom bots)
--agent-name "My Bot" — for agents without auto-detection
HTTP Headers (HTTP mode)
X-Agent-Id, X-Agent-Name — for HTTP-based integrations
Note: Most AI clients (Claude Code, Gemini CLI) automatically send their name during the connection handshake. For custom agents, use --agent-name or HTTP headers.
What are AI Tool Servers?
AI tool servers provide capabilities that AI agents use to interact with the outside world. Each server provides specific tools:
@modelcontextprotocol/server-filesystem
Gives AI agents the ability to read, write, and search files on your computer. Tools: read_file, write_file, list_directory, search_files, etc.
@playwright/mcp
Gives AI agents the ability to control a web browser — navigate pages, click buttons, fill forms, take screenshots. Tools: browser_navigate, browser_click, browser_screenshot, etc.
Why SolonGate? These tools are powerful — an AI agent could read sensitive files or navigate to malicious sites. SolonGate sits between the AI and these tools, enforcing security policies on every call.
Setup (.mcp.json)
Add SolonGate proxy to your project's .mcp.json file. The proxy auto-detects which AI client is connected (Claude Code, Gemini CLI, etc.) from the client handshake — no configuration needed:
1{2 "mcpServers": {3 "filesystem": {4 "command": "npx",5 "args": [6 "-y", "@solongate/proxy@latest",7 "--", "npx", "-y",8 "@modelcontextprotocol/server-filesystem@latest", "."9 ],10 "env": {11 "SOLONGATE_API_KEY": "${SOLONGATE_API_KEY}"12 }13 },14 "playwright": {15 "command": "npx",16 "args": [17 "-y", "@solongate/proxy@latest",18 "--", "npx", "-y",19 "@playwright/mcp@latest"20 ],21 "env": {22 "SOLONGATE_API_KEY": "${SOLONGATE_API_KEY}"23 }24 }25 }26}
How it works: The proxy wraps each tool server. When Claude Code calls read_file, the request goes through SolonGate first — it checks policies, logs the call, then forwards to the real filesystem server. Agent identity is auto-detected from the client handshake — Claude Code appears as claude-code, Gemini CLI as gemini-cli, etc. If multiple AI clients use the same project, each gets its own trust map node.
CLI Usage
You can also run the proxy directly from terminal:
1# With -- separator2npx @solongate/proxy@latest -- npx -y @modelcontextprotocol/server-filesystem@latest .34# Without -- (also works — proxy auto-detects upstream command)5npx @solongate/proxy@latest npx -y @playwright/mcp@latest
HTTP Headers (HTTP mode)
1# Start proxy in HTTP mode2solongate-proxy --port 3100 -- npx @playwright/mcp@latest34# Send requests with agent identity headers5curl -X POST http://localhost:3100/mcp \6 -H "X-Agent-Id: my-custom-bot" \7 -H "X-Agent-Name: My Custom Bot" \8 -H "Content-Type: application/json" \9 -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"file_read","arguments":{"path":"README.md"}}}'
Automatic (Client Detection)
1// When an AI client connects, SolonGate reads clientInfo from the2// initialize handshake — no configuration needed.3//4// Example: Claude Code sends:5// { "name": "claude-code", "version": "1.0.32" }6//7// SolonGate captures this as:8// agent_id: "claude-code/1.0.32"9// agent_name: "claude-code"
Trust Score Algorithm
Each agent gets a trust score from 0 to 1 (shown as 0-100%) based on their behavior:
allowedCalls / totalCalls
1 - (piDetections / totalCalls)
Active in last 24h = 1.0, 7d = 0.5
trustScore = (allowRate * 0.6) + (cleanRate * 0.3) + (recency * 0.1)Trust Levels
Trust scores map to visual indicators on the graph and table:
80-100%
Agent behaves normally, few denials
60-79%
Some denials or PI detections
40-59%
Significant denials or PI activity
0-39%
Mostly denied, potential threat
Agent Relationships (Edges)
The trust map doesn't just show individual agents — it shows how they relate to each other through shared tool usage.
Shared Tool Usage
Two agents are connected if they both called the same tool(s) within the same project. For example, if Agent A and Agent B both use file_read and shell_exec, they share an edge.
Edge Thickness
Thicker edges mean more shared interactions. Edge trust score is the minimum of both agents' trust scores.
Agent Groups
Groups let you categorize agents and apply per-group policy rules. For example, a "Backend" group could allow all tools, while a "Guest" group is restricted to read-only operations.
Dashboard: Trust Map → Groups tab
Create a group, set a color, add policy rules (tool pattern + ALLOW/DENY), then add agents as members. Agents inherit the group's rules. On the graph, group members share a colored border and a convex hull background.
How to create a group
policy.jsonpolicy.json example
1{2 "rules": [...],3 "agentTrustMap": {4 "groups": {5 "backend": {6 "description": "Trusted backend agents",7 "members": ["claude-code", "cursor"],8 "rules": [9 { "toolPattern": "*", "effect": "ALLOW" }10 ]11 },12 "guest": {13 "description": "Read-only guest agents",14 "members": ["unknown-bot"],15 "rules": [16 { "toolPattern": "file_read", "effect": "ALLOW" },17 { "toolPattern": "*", "effect": "DENY" }18 ]19 }20 }21 }22}
DENY wins: If both local policy.json and cloud dashboard define rules for the same agent, DENY from either source blocks the tool call. Groups created in the dashboard are stored in the cloud DB, while policy.json groups are local-only.
Agent Relationships
Relationships define explicit trust rules between two agents. Unlike auto-computed edges (based on shared tool usage), relationships are manually created and enforced.
Three relationship types
How to create a relationship
policy.json example
1{2 "agentTrustMap": {3 "relationships": [4 {5 "source": "claude-code",6 "target": "gemini-cli",7 "type": "peer",8 "allowedTools": ["file_read", "file_write"],9 "deniedTools": ["shell_exec"]10 },11 {12 "source": "orchestrator",13 "target": "sub-agent-1",14 "type": "delegation",15 "allowedTools": ["file_read"]16 }17 ]18 }19}
Enforcement: When an agent makes a tool call, the proxy checks if a relationship exists. If deniedTools matches, the call is blocked. If allowedTools is set and the tool isn't in the list, it's also blocked. Relationships can be edited or deleted after creation from the dashboard.
Delegation Chains
Delegation chains model multi-hop permission flows: A delegates to B, B delegates to C. The effective permissions at each hop are computed by intersecting the allowed tools of each relationship in the chain — permissions can only get narrower, never broader.
How to create a delegation chain
Important: Delegation chains are one-directional (A → B → C). Each link in the chain must have a corresponding Relationship. For bidirectional rules, use Relationships instead. Delegations are immutable — create or revoke, no editing.
policy.json example
1{2 "agentTrustMap": {3 "delegations": [4 {5 "chain": ["claude-code", "sub-agent-1", "sub-agent-2"],6 "effectiveTools": ["file_read"]7 }8 ]9 }10}
How effective tools are computed: If Claude Code → Sub-Agent allows [file_read, file_write] and Sub-Agent → Sub-Agent-2 allows [file_read, shell_exec], the effective tools for the chain are the intersection: [file_read] only.
Local Policy: agentTrustMap
The agentTrustMap section in policy.json lets you define groups, relationships, and delegations locally. These rules are enforced by both the proxy and guard.mjs hook, even without a cloud connection.
1{2 "id": "my-policy",3 "name": "Project Policy",4 "description": "Security policy for my project",5 "version": 1,6 "rules": [7 {8 "id": "r1",9 "description": "Allow file reads",10 "effect": "ALLOW",11 "priority": 100,12 "toolPattern": "file_read",13 "minimumTrustLevel": "UNTRUSTED",14 "enabled": true,15 "createdAt": "2026-01-01T00:00:00Z",16 "updatedAt": "2026-01-01T00:00:00Z"17 }18 ],19 "agentTrustMap": {20 "groups": {21 "trusted": {22 "members": ["claude-code", "cursor"],23 "rules": [{ "toolPattern": "*", "effect": "ALLOW" }]24 },25 "restricted": {26 "members": ["unknown-bot"],27 "rules": [28 { "toolPattern": "file_read", "effect": "ALLOW" },29 { "toolPattern": "*", "effect": "DENY" }30 ]31 }32 },33 "relationships": [34 {35 "source": "claude-code",36 "target": "cursor",37 "type": "peer",38 "allowedTools": ["file_read", "file_write"]39 }40 ],41 "delegations": [42 {43 "chain": ["claude-code", "sub-agent"],44 "effectiveTools": ["file_read"]45 }46 ]47 },48 "createdAt": "2026-01-01T00:00:00Z",49 "updatedAt": "2026-01-01T00:00:00Z"50}
Two rule sources: Rules from policy.json (local) and from the Dashboard (cloud) are both evaluated. DENY wins — if either source denies, the tool call is blocked. This means the Dashboard can add restrictions on top of local policy, and local policy can restrict tools that the Dashboard allows.
API Reference
The trust map data is available via the REST API:
1# Get trust map data2curl -H "Authorization: Bearer sg_live_xxx" \3 "https://api.solongate.com/api/v1/trust-map?period=7d"45# Response:6{7 "nodes": [8 {9 "id": "claude-code@key123",10 "name": "claude-code",11 "trustScore": 0.92,12 "totalCalls": 150,13 "allowed": 145,14 "denied": 5,15 "piDetections": 1,16 "lastSeen": "2026-03-14T10:00:00Z",17 "groupId": "grp-1",18 "groupName": "Backend",19 "groupColor": "#6366f1",20 "tools": ["file_read", "file_write", "shell_exec"]21 }22 ],23 "edges": [24 {25 "source": "claude-code",26 "target": "gemini-cli",27 "sharedTools": ["file_read"],28 "interactionCount": 23,29 "trustScore": 0.85,30 "isComputed": false,31 "relationship": {32 "id": "rel-1",33 "type": "peer",34 "trustLevel": "VERIFIED",35 "allowedTools": ["file_read"],36 "deniedTools": []37 }38 }39 ],40 "groups": [41 {42 "id": "grp-1",43 "name": "Backend",44 "color": "#6366f1",45 "memberCount": 246 }47 ],48 "delegations": [49 {50 "id": "del-1",51 "chain": ["claude-code", "sub-agent"],52 "effectiveTools": ["file_read"],53 "status": "active"54 }55 ],56 "summary": {57 "totalAgents": 3,58 "totalInteractions": 45,59 "avgTrustScore": 0.88,60 "groupCount": 161 }62}
Query Parameters
| Parameter | Default | Description |
|---|---|---|
period | 30d | Time window: 24h, 7d, or 30d |
Testing the Trust Map
To verify the trust map is working end-to-end:
Run proxy with an agent name
1npx @solongate/proxy@latest -- npx -y @playwright/mcp@latest
Make some tool calls through the proxy
Use Claude Code, Gemini CLI, or any AI client connected through the proxy. Each tool call is logged with the agent identity.
Check the API
1curl -H "Authorization: Bearer sg_live_xxx" \2 "https://api.solongate.com/api/v1/trust-map"
You should see your agent in the nodes array.
Open the Dashboard
Go to Trust Map in the sidebar. Your agent should appear as a node with its trust score. If multiple agents connect, edges will form between agents that share the same tools.
Sub-Agent Tracking
When an AI client spawns sub-agents (e.g. Claude Code's Task tool), they share the same connection. SolonGate can still track each sub-agent individually using the _meta field or HTTP headers.
Option 1: _meta field
Include sub-agent identity in the _meta field of each tools/call request:
1{2 "jsonrpc": "2.0",3 "method": "tools/call",4 "params": {5 "name": "file_read",6 "arguments": { "path": "README.md" },7 "_meta": {8 "io.solongate/agent": {9 "id": "researcher",10 "name": "Research Agent"11 }12 }13 }14}
The proxy reads io.solongate/agent from _meta and creates a composite agent ID: parent-agent::researcher. This appears as a separate node in the trust map, linked to its parent.
Option 2: HTTP Headers (HTTP mode)
1# Start proxy in HTTP mode2solongate-proxy --port 3100 -- npx @playwright/mcp@latest34# Send requests with sub-agent identity5curl -X POST http://localhost:3100/mcp \6 -H "X-Agent-Id: claude-code" \7 -H "X-Sub-Agent-Id: researcher" \8 -H "X-Sub-Agent-Name: Research Agent" \9 -H "Content-Type: application/json" \10 -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"file_read","arguments":{"path":"README.md"}}}'
Visual cue: Sub-agents appear as smaller nodes with dashed borders in the trust map. Parent→sub-agent edges are shown as dotted lines.
Per-Agent Audit Logs
When you expand an agent row in the Trust Map dashboard, you see that agent's audit logs — fetched directly from the API with server-side filtering.
agent_name parameter — only that agent's logs are returned. No client-side filtering from a generic pool.API Endpoint
1# Fetch logs for a specific agent2curl -H "Authorization: Bearer sg_live_..." \3 "https://api.solongate.com/api/v1/audit-logs?agent_name=claude-code&limit=50&offset=0"45# Response6{7 "entries": [...], // Only claude-code logs8 "total": 103, // Total claude-code logs (not all agents)9 "limit": 50,10 "offset": 011}
Tips
Click a node in the graph to highlight its connections and see detailed stats.
Period selector lets you view 24h, 7d, or 30d of data. Use shorter periods for recent activity.
No agents showing? Make sure you're using a sg_live_ key. Test keys (sg_test_) skip audit log forwarding.