A peer connection is not a phone contact
Scheduled6 min read By NT²
Sharing to “someone in Contacts” only works if the row holds encryption material for that vault—not a phone number you hope matches the right person.
A peer connection is not a phone contact
Claim: identity and encryption are different jobs
Phone address books answer “how do I reach this person?” NT² Contacts answer a harder pair of questions: which vault am I recognizing, and what keys seal a package to them?
Those are not the same job.
A Vault Key DID is the counterparty’s public vault identity. It is what fingerprints, signatures, and cloud proofs hang from. It tells you who the vault claims to be across invites, share packages, and optional edge auth.
A peer connection is the durable relationship between your vault and theirs. Inside that relationship, Peer DID material is the encryption endpoint for vault-to-vault (Mode A) packages. Mode A encrypt and decrypt use Peer documents—not the Key DID as a catch-all keyAgreement surface.
The claim in one line: a contact row is a peer connection—Key DID for who, Peer DID for how you encrypt—not a phone-book entry you paste and hope.
That split is the crypto half of stories already told in plain language: secure contacts are trust relationships, one-way invite versus mutual trust, and verified trust is cryptographic. Selective SSI refuses to turn the vault into a general DIDComm wallet—see selective SSI, not a DID wallet—while still needing a concrete peer handoff for Mode A.
Constraint: pasted identifiers invite the wrong recipient
Engineers and products often want a shortcut: type a DID, tap Save, start sharing. It feels like adding an email to a mail client.
The shortcut fails for vault-to-vault encryption.
If you encrypt to a Key DID agreement key you invented in your head, you may not be encrypting to the peer the product will use later. Identity and per-relationship encryption must stay separable. Conflating them invites “helpful” paths that seal packages to the wrong document, or that treat a signing identity as an encryption endpoint.
If contacts can be created by pasting identifiers without an invite, wrong-recipient risk rises. A mistyped DID, a QR from the wrong screen, or a forwarded string becomes a durable address book row. Mode A then happily encrypts to whoever that string named. Invite-first OOB makes the counterparty present their Key DID and Peer DID material as a signed handoff, not as a free-text field you invent alone.
If one-way accept silently enables outbound Mode A, you encrypt to a half-known peer. Accepting someone’s invite lets you verify what they send and stage packages in Inbox. Sending encrypted Mode A back needs their peer encryption material on your side—and that arrives when the reciprocal invite closes. Blocking send until the peer connection is complete is uglier UX than “just send.” It is safer than sealing to incomplete material.
If “verified” is a button, cryptography becomes cosplay. Trust state should move when proof events happen—invite completion, fingerprint confirmation, successful Accept of a package—not when a user promotes a row because the display name looks familiar.
The constraint is therefore social and cryptographic at once: do not invent a recipient; complete a peer connection.
Design: invite-first OOB, then Mode A to the peer
NT²’s contact path is invitation-shaped.
- Side A shares an invite (QR, deep link, or other OOB carrier) that carries their Vault Key DID and Peer DID material for this relationship.
- Side B accepts. B stores A as a contact and holds A’s peer encryption endpoint for inbound verification and future encrypt-to-A once mutual.
- For mutual send, B returns a reciprocal invite with B’s Key DID and Peer DID.
- A completes the reciprocal scan on the pending contact. Both vaults now hold each other’s identity and peer encryption material.
flowchart LR
subgraph identity [Identity]
KD[Vault Key DID]
end
subgraph relationship [Peer connection]
PD[Peer DID material]
Wrap[Wrapped at rest under vault key]
PD --> Wrap
end
KD -->|names the counterparty| Contact[Contacts row]
Wrap --> Contact
Contact -->|Mode A encrypt| Pkg[Vault-to-vault package]
Invite-first. Address-book rows originate from invitation, not from “Add contact” forms that accept pasted Key DIDs as the primary path. The inviter proves possession; the invitee chooses to recognize them.
Random Peer DID per connection. Each peer connection gets its own Peer DID key material for that counterparty relationship. Private peer keys are wrapped at rest under the local vault key and only unwrapped while the vault is unlocked—same session honesty as other vault secrets.
Mode A addresses the peer connection. Vault-to-vault packages use ECDH → HKDF → AES-GCM under a vault-to-vault domain label, signed by the sender’s Vault Key DID. The encryption endpoint is the Peer DID document from the connection row. Opening the package requires the recipient’s unlocked vault—not a disposable share passphrase. That boundary sits beside share passphrase ≠ master password: Mode A refuses the passphrase model because the trust shape is a known vault relationship.
One-way versus mutual. Accepting an invite is real trust for inbound. Mutual Mode A send waits on reciprocal peer material. The product prefers an explicit “relationship incomplete” state over a silent wrong-recipient encrypt.
Contacts stay local. Who you are connected with is privacy-sensitive. Contact and peer rows live in the vault’s local store. Premium sync may replicate encrypted contact state across your devices; that is still not a public social graph on the edge.
Trade-off: relationship friction instead of wrong-recipient convenience
Invite-first peer connections cost steps.
Two people must complete OOB exchange before Mode A feels like chat. One-way accept is not “we can both send.” Fingerprint confirmation still matters for high-stakes relationships. Engineers cannot collapse Key DID and Peer DID into one document “to simplify the schema.”
Support language must stay precise. Contacts are not the phone app. Peer connection is not an ephemeral nearby session. A temporary proximity transport that never learns Key DIDs is a different layer; this essay is about durable identity-bound relationships for Mode A.
We accept the friction because blast radius stays honest. Encrypting to a completed peer connection limits who can open the package to a vault that holds matching peer material. Inventing a recipient from a pasted string optimizes for speed and fails as wrong-person ciphertext that still looks successful.
When the other party will never install NT², Mode A is the wrong tool. Encrypted links and .nt2share files use a share passphrase instead—see the Mode B/C deepen later in this series, and the primer share passphrase ≠ master password.
What we refuse
We refuse Mode A encryption to a contact without peer encryption material. Incomplete relationships do not get a “send anyway” that seals to guesswork.
We refuse to conflate Vault Key DID identity with Peer DID encryption endpoints. Signing who they are is not the same as sealing a package to them.
We refuse primary “paste a DID and save” contact creation as the product path. Invite-first OOB is how peer material arrives.
We refuse a manual “Mark verified” promotion that skips cryptographic proof events. Verified state follows proofs, not optimism.
We refuse treating the phone address book as the trust list for vault handoffs. Numbers and emails do not encrypt Mode A packages.
Close: contacts are peer connections
Cross-vault sharing starts with who you are willing to recognize as a vault. That recognition is a peer connection: Key DID for identity, Peer DID material for encryption, invite-first OOB to bind them, and mutual completion when both sides need to send.
Inbox still asks Accept on inbound packages—see relay indexes ciphertext; Inbox stays local. Outbox tracks what you already sent—next in this series. Unlock never becomes the share secret; peer keys never become a phone contact you mistyped.
If you want vault-to-vault handoffs that wait for real peer material, explore NT² Vault.
Last updated 2026-12-03
Related stories
- A proximity session is not a peer connection
5 min read
- Selective SSI — not a general DIDComm wallet
9 min read
- Share passphrase ≠ master password
8 min read