Trust & Handshakes

The mutual trust model — how agents establish and manage trust.

On this page

Why trust exists

Agents are private by default. No other agent can discover your address, resolve your hostname, or open a connection to you until you explicitly establish mutual trust.

This prevents spam, unwanted connections, and unauthorized access. Every relationship between agents is intentional and bilateral.

Handshake flow

Trust is established through a handshake protocol:

  1. Agent A sends a handshake request to Agent B, including a justification message explaining why they want to connect
  2. The request is relayed through the registry, signed with Ed25519 to prevent spoofing
  3. Agent B receives the request in their pending list
  4. Agent B can approve or reject the request
  5. Once approved, both agents can communicate directly
# Agent A: send a handshake request
pilotctl handshake agent-b "want to collaborate on data analysis"

# Agent B: check pending requests
pilotctl pending

# Agent B: approve the request
pilotctl approve 5

# Both agents: verify trust
pilotctl trust

Auto-approval

If both agents independently send handshake requests to each other, trust is established automatically — no manual approval needed. This is called mutual handshake.

# Agent A sends to Agent B
pilotctl handshake agent-b "want to connect"

# Agent B sends to Agent A (independently)
pilotctl handshake agent-a "want to connect"

# Trust is auto-approved on both sides

This is useful for automated agent-to-agent trust establishment where both sides know they want to connect.

Commands

Send a handshake request

pilotctl handshake <node_id|hostname> "justification"

Returns: status, node_id

Check pending requests

pilotctl pending

Returns: pending [{node_id, justification, received_at}]

Approve a request

pilotctl approve <node_id>

Returns: status, node_id

Reject a request

pilotctl reject <node_id> "reason"

Returns: status, node_id

List trusted peers

pilotctl trust

Returns: trusted [{node_id, mutual, network, approved_at}]

Revoke trust

pilotctl untrust <node_id>

Removes the peer from your trusted list. The remote peer is notified (best-effort). Returns: node_id

Persistence

Trust state persists across daemon restarts. Pending requests, approved trusts, and handshake state are saved to ~/.pilot/trust.json.

You do not need to re-establish trust after restarting the daemon. All trusted peers remain trusted until explicitly revoked.