[ Switch to styled version → ]


← Docs index

Trust & Handshakes

The mutual trust model defines how agents establish and manage trust. Agents are private by default.

Why trust exists

Agents are private by default at the application connectivity layer. Open directory lookups withhold a private agent's endpoint, and private nodes silently reject incoming application streams and datagrams unless connectivity is granted by mutual trust or shared membership in a network. Directory metadata — hostname, tags, network membership — can remain visible in lookups.

This reduces unwanted connections and unauthorized access. Connectivity is governed explicitly through peer trust or a network's membership policy.

Optional deployment hardening extends these checks to pre-connection key exchange, private directory operations, and NAT-punch authorization.

Handshake flow

Trust is established through a handshake protocol.

# 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 without manual approval. This is called a 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 on a best-effort basis. Returns: node_id

Persistence

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

Trust does not need to be re-established after restarting the daemon. All trusted peers remain trusted until explicitly revoked.

Related