Skip to main content

Pair Two Machines

Pairing transfers one opaque ticket from an existing peer to a joining peer. The ticket contains protocol version, the random 256-bit group secret, the exporting endpoint ID, and its signing-key fingerprint. Treat the complete ticket as a secret: do not paste it into logs, issue trackers, shell history, or release evidence.

Identity map​

IdentityShared?PersistencePurpose
256-bit group secretYes, only within the paired groupStored in each mode-0600 P2P identity fileDerives the private gossip topic
iroh endpoint secret/keyNoAtomically persisted across restartsGives one peer a stable endpoint ID
Endpoint allow-list bindingEach peer enrolls the otherPersisted with P2P identityBinds endpoint ID to signing-key fingerprint
KBD project IDOnly for replicas of one projectRepository manifest + runtime registryNames one KBD authority
KBD device keyNoCredential store or mode-0600 fileSigns KBD commands/events

The removed operator_id is not a pairing credential. New groups use a random secret and explicit enrollment, so a guessable name cannot join a topic.

1. Initialize stable identities​

Run on both machines with their own config:

sovereign-sync --mode init

The output reports the P2P identity path and endpoint ID, never the group secret. The identity file must be regular, atomically written, and mode 0600.

2. Export on the existing peer​

On Machine A:

PAIR_TICKET="$(sovereign-sync --mode pair-export)"

Transfer PAIR_TICKET through an authenticated confidential channel. Do not use set -x, command tracing, CI variables, or chat transcripts.

3. Import on the joining peer​

On Machine B:

sovereign-sync --mode pair-import --ticket "$PAIR_TICKET"

Import validates the ticket protocol, 32-byte group secret, endpoint ID, and fingerprint binding before persisting the group and allow-list entry. The command prints only the paired endpoint and fingerprint.

Export Machine B’s ticket and import it on Machine A so both sides have explicit allow-list bindings:

# Machine B
PAIR_TICKET_B="$(sovereign-sync --mode pair-export)"

# Machine A, after confidential transfer
sovereign-sync --mode pair-import --ticket "$PAIR_TICKET_B"

4. Start isolated peers and verify​

The default local API is a Unix socket; it does not open port 7892:

SOCKET_PATH="$HOME/.prometheus/run/sovereign-sync.sock"
sovereign-sync --mode daemon --socket "$SOCKET_PATH"
curl --unix-socket "$SOCKET_PATH" \
http://localhost/health

Use the actual socket path reported by your installation on macOS. Loopback TCP is opt-in with --tcp and requires a bearer token loaded from a mode-0600 file.

Create a signed v2 push, then poll its durable receipt or resume the event stream. A local broadcast state alone is not peer application evidence. Certification requires a per-peer received, applied, or rejected receipt and proves the same terminal receipt survives restart.

Rejection behavior​

Inbound frames fail closed when the endpoint is unknown, the group secret/topic does not match, the endpoint and signing key disagree, the request is stale, or a request ID is replayed. The full ticket and group secret are never logged.

To remove a peer, delete its endpoint-to-signing-key binding through the supported identity-management path and restart the isolated peer. Creating a new group secret is a group rotation, not an operator_id rename.