Connecting with Others
Unlike traditional applications where users connect through central servers, Osvauld users establish direct peer-to-peer connections through cryptographic handshakes. This process ensures that only authorized users can connect while maintaining complete decentralization.
Two Connection Pathways
Section titled “Two Connection Pathways”There are two ways users can connect to each other:
1. Direct Connection via One-Time Token
Section titled “1. Direct Connection via One-Time Token”A user generates a temporary connection token that others can use to establish trust and connect directly.
2. Delegated Connection via Resource Sharing
Section titled “2. Delegated Connection via Resource Sharing”When a user shares a resource that’s already shared with others, those collaborators receive delegated connection tokens to connect directly with the new user.
One-Time Connection Token
Section titled “One-Time Connection Token”Token Structure
Section titled “Token Structure”The one-time connection token is a UCAN with specific characteristics:
{ "alg": "EdDSA", "typ": "JWT"}{ "aud": "*", "cap": { "livnote:user-connect:alice_user_id": {"use": [{}]} }, "exp": 1756453132, "iss": "alice_did", "ucv": "0.10.0-canary"}
Key properties:
- Algorithm (
alg
): EdDSA signature algorithm - Type (
typ
): JWT token type - Issuer (
iss
): The user’s UCAN public key as a DID - Audience (
aud
): Wildcard*
allowing anyone to use it - Expiration (
exp
): Unix timestamp for 24-hour validity period - Capability (
cap
):user-connect
permission for the issuer’s user ID - UCAN Version (
ucv
): Version 0.10.0-canary
Permanent Connection Token
Section titled “Permanent Connection Token”After successful handshake, users exchange permanent tokens with extended capabilities:
{ "alg": "EdDSA", "typ": "JWT"}{ "aud": "bob_did", "cap": { "livnote:user-connect:alice_user_id": {"use": [{}]}, "livnote:user-share:alice_user_id": {"use": [{}]} }, "exp": 2702146687, "iss": "alice_did", "ucv": "0.10.0-canary"}
Key properties:
- Specific Audience: Targeted to the recipient’s DID instead of wildcard
- Dual Capabilities: Both
user-connect
anduser-share
permissions - Long Lifetime: 30-year validity (exp: 2702146687)
- Bidirectional: Both users issue similar tokens to each other
Delegated Connection Token
Section titled “Delegated Connection Token”When sharing resources creates transitive connections, delegated tokens contain embedded proof chains:
{ "alg": "EdDSA", "typ": "JWT"}{ "aud": "carol_did", "cap": { "livnote:user-connect:bob_user_id": {"use": [{}]} }, "exp": 2702146687, "iss": "alice_did", "prf": ["parent_token_cid"], "fct": { "proof": "alice_permanent_token_for_bob" }, "ucv": "0.10.0-canary"}
Key properties:
- Specific Audience: Targeted to Carol’s DID instead of wildcard
- Connect Capability: Permission for Carol to connect to Bob
- Long Lifetime: 30-year validity matching permanent tokens
- Proof Reference (
prf
): CID of parent token in standard UCAN proof field - Embedded Proof (
fct.proof
): Full parent token embedded in facts field - Delegated Authority: Alice issues token allowing Carol-Bob connection
- Chain Validation: Bob can verify the delegation chain back to Alice’s authority
This dual-proof mechanism (both CID reference and embedded token) ensures the delegation chain can be validated even when the proof resolver cannot find the parent token by CID.
Connection Flow Scenarios
Section titled “Connection Flow Scenarios”Scenario 1: First-Time Connection
Section titled “Scenario 1: First-Time Connection”
Scenario 2: Delegated Connection
Section titled “Scenario 2: Delegated Connection”
Connection Establishment Process
Section titled “Connection Establishment Process”QUIC Connection Setup
Section titled “QUIC Connection Setup”Before any handshake messages, peers establish a secure transport connection:
- Peer Discovery: Using Iroh’s default discovery mechanism to find the target device by its device key (node ID)
- QUIC Connection: Direct encrypted connection using device keys for authentication
- Channel Security: Device keys encrypt the QUIC transport layer
Identity Verification During Handshake
Section titled “Identity Verification During Handshake”All handshake messages include PGP signature verification:
// Extract UCAN public key from PGP-signed messagelet peer_ucan_pub = crypto_utils::verify_clear_text_message( &payload.peer_user.public_key, // PGP public key &payload.signed_ucan_pub, // PGP-signed UCAN public key (10min validity)).await?;
This process:
- Parses PGP Certificate: Validates the peer’s PGP public key format
- Verifies Cleartext Signature: Uses PGP to verify the signed UCAN public key
- Checks Signature Validity: PGP signature has 10-minute expiration for freshness
- Extracts Message: Returns the original UCAN public key if signature is valid
- Binds Identity: Cryptographically links PGP identity to UCAN permissions
Handshake Message Types
Section titled “Handshake Message Types”The handshake protocol uses different message flows depending on whether this is a first-time connection or an existing relationship:
First-Time Connection Flow
Section titled “First-Time Connection Flow”When users connect for the first time (marked as first_sync = false
in the database), they exchange complete identity information:
FirstConnectRequest - Initial connection with one-time or delegated token:
FirstConnectRequest { devices: Vec<Device>, // Initiator's device list issued_ucan: String, // Permanent UCAN for responder signed_ucan_pub: String, // Initiator's UCAN pub key, PGP-signed one_time_ucan: String, // Connection token (one-time or delegated) peer_device: Device, // Initiator's current device peer_user: User, // Initiator's user identity connection_type: ConnectionType, // Purpose of connection}
FirstConnectResponse - Complete identity exchange:
FirstConnectResponse { peer_user: User, // Responder's identity peer_device: Device, // Responder's current device devices: Vec<Device>, // Responder's complete device list ucan_token: String, // Initiator's permanent UCAN issued_ucan: String, // Responder's permanent UCAN for initiator signed_ucan_pub: String, // Responder's UCAN pub key, PGP-signed}
After this exchange:
- Both users mark each other as
first_sync = true
- Complete device lists are stored
- Permanent UCANs with connect + share capabilities are exchanged
- Future connections use the simpler UcanAndUserExchange flow
Regular Connection Flow
Section titled “Regular Connection Flow”For established connections (first_sync = true
), only current session information is exchanged:
UcanAndUserExchange - Used for both initiator and responder:
UcanAndUserExchange { ucan_token: String, // Permanent UCAN for peer peer_user: User, // Sender's identity peer_device: Device, // Sender's current device connection_type: ConnectionType, // Connection purpose signed_ucan_pub: String, // Sender's UCAN pub key, PGP-signed (10min validity)}
This simpler flow is used because:
- Identities are already known and stored
- Only current device/session info needs verification
- Permanent UCANs are already established
Handshake Validation Steps
Section titled “Handshake Validation Steps”Token Validation
Section titled “Token Validation”- Structure Check: Parse UCAN format and verify required fields
- Signature Verification: Validate cryptographic signature
- Expiration Check: Ensure token hasn’t expired
- Capability Check: Confirm
user-connect
permission exists - Audience Validation: For permanent tokens, verify audience matches presenter
Identity Verification
Section titled “Identity Verification”- PGP Signature Check: Verify signed UCAN public key with PGP certificate
- UCAN Key Extraction: Extract and validate UCAN public key from signature
- Consistency Check: Ensure UCAN key matches token issuer/audience
Delegation Chain Validation
Section titled “Delegation Chain Validation”For delegated connections, validate the embedded proof chain:
- Parse Embedded Proof: Extract parent token from facts field
- CID Verification: Ensure embedded proof CID matches proof reference
- Recursive Validation: Follow chain back to root authority
- Capability Inheritance: Verify each link has necessary permissions
Connection Types and Actions
Section titled “Connection Types and Actions”After handshake completion, connections can serve different purposes:
- UserSync: General user data synchronization
- LiveEdit: Real-time document collaboration
- DeviceSync: Synchronizing between user’s own devices
- AddDevice: Adding a new device to user’s identity
Security Properties
Section titled “Security Properties”The handshake protocol ensures:
Mutual Authentication: Both peers prove their identities cryptographically
Perfect Forward Secrecy: QUIC channels use ephemeral keys for transport encryption
Capability-Based Access: UCAN tokens provide precise permission control
Delegation Integrity: Proof chains ensure delegated permissions are legitimate
Replay Protection: Token expiration prevents reuse of old credentials
Identity Consistency: PGP signatures bind UCAN keys to stable identities
What Happens After Handshake
Section titled “What Happens After Handshake”Once the handshake completes successfully:
- Persistent Storage: Each peer stores the other’s identity and UCAN tokens in their local database
- Connection Ready: Peers can now share resources and collaborate
- Future Connections: Subsequent connections use permanent UCANs instead of one-time tokens
- Resource Sharing: Users can grant each other access to documents and other resources
- Delegation Capability: Each user can now delegate connection permissions to others on behalf of their peer
The handshake establishes not just connectivity, but a cryptographic trust relationship that enables all future collaboration between the peers.