# CookieBridge Architecture ## Overview CookieBridge is a cross-device cookie sync system built on a zero-knowledge relay architecture. The relay server transports and stores encrypted cookie blobs but cannot decrypt them. All cryptographic operations happen client-side. ## Components ### Relay Server (`src/relay/`) A plain Node.js HTTP + WebSocket server. No frameworks — just `http`, `ws`, and `sodium-native`. - **server.ts** — Routes HTTP requests and upgrades WebSocket connections. Single entry point for all API traffic. - **connections.ts** — Manages active WebSocket connections. Maps device IDs to sockets for real-time push. - **auth.ts** — Two auth methods: - **Token auth**: Bearer tokens issued at device registration. Used for HTTP and WebSocket. - **Challenge-response**: Server sends random bytes, client signs with Ed25519. Used for WebSocket upgrade. - **store.ts** — In-memory encrypted cookie blob storage. Keyed by `(deviceId, domain, cookieName, path)`. Limit: 10,000 cookies per device. - **tokens.ts** — Device and agent registries. Tracks device metadata, pairing relationships, and agent access grants. ### Cryptography (`src/crypto/`) All crypto uses libsodium via `sodium-native` (server) or `libsodium-wrappers-sumo` (extension). | Operation | Algorithm | Purpose | |-----------|-----------|---------| | Encryption | XChaCha20-Poly1305 | Cookie payload encryption (AEAD) | | Signing | Ed25519 | Message authentication, device identity | | Key exchange | X25519 | Deriving shared secrets between paired devices | | Key derivation | BLAKE2b (generic hash) | Deriving encryption keys from ECDH output | ### Sync Engine (`src/sync/`) - **envelope.ts** — Wire format for WebSocket messages. Each message is signed and encrypted. - **conflict.ts** — Last-writer-wins (LWW) conflict resolution. Uses Lamport clock timestamps. Ties broken by lexicographic device ID comparison. ### Browser Extension (`extension/`) Single TypeScript codebase compiled per-browser via esbuild. - **service-worker.ts** — Extension lifecycle, device registration, pairing orchestration, sync triggers. - **api-client.ts** — HTTP client for relay server REST API. - **connection.ts** — WebSocket manager with auto-reconnect and exponential backoff. - **crypto.ts** — Client-side encryption/decryption using libsodium-wrappers-sumo. - **sync.ts** — Processes incoming cookie updates, applies them via `chrome.cookies` API. - **compat.ts** — Cross-browser abstraction layer for Chrome, Firefox, Edge, Safari API differences. ## Data Flow ### Device Registration ``` Extension Relay Server │ │ │ POST /api/devices/register │ │ { deviceId, name, platform, │ │ encPub } │ │──────────────────────────────────▶│ │ │ │ { token, deviceId, ... } │ │◀──────────────────────────────────│ ``` ### Pairing ``` Device A Relay Server Device B │ │ │ │ POST /api/pair │ │ │ { deviceId, x25519Pub,│ │ │ pairingCode } │ │ │──────────────────────▶│ │ │ │ │ │ │ POST /api/pair/accept │ │ │ { deviceId, x25519Pub,│ │ │ pairingCode } │ │ │◀──────────────────────│ │ │ │ │ { peerX25519PubKey } │ { peerX25519PubKey } │ │◀──────────────────────│──────────────────────▶│ │ │ │ │ derive shared secret │ derive shared secret │ │ (X25519 ECDH) │ (X25519 ECDH) │ ``` ### Cookie Sync (WebSocket) ``` Device A Relay Server Device B │ │ │ │ cookie_sync envelope │ │ │ (signed + encrypted) │ │ │──────────────────────▶│ │ │ │ store encrypted blob │ │ │ │ │ │ forward envelope │ │ │──────────────────────▶│ │ │ │ │ │ decrypt│ │ │ apply │ │ ack │ │ │◀──────────────────────│◀──────────────────────│ ``` ### Cookie Sync (HTTP Polling) ``` Device Relay Server │ │ │ POST /api/cookies │ │ { encrypted blob } │ │───────────────────────────────▶│ │ │ │ GET /api/cookies/updates │ │ ?since= │ │───────────────────────────────▶│ │ │ │ [ encrypted blobs ] │ │◀───────────────────────────────│ ``` ## Storage All storage is **in-memory**. The relay server does not persist data to disk. Restarting the server clears all registrations, pairings, and stored cookies. Devices re-register and re-sync automatically on reconnection. This is intentional for the current version — the server is a transient relay, not a database. Persistent storage may be added in a future milestone. ## Protocol Constants | Constant | Value | Purpose | |----------|-------|---------| | `PROTOCOL_VERSION` | `2.0.0` | Wire protocol version | | `MAX_STORED_COOKIES_PER_DEVICE` | 10,000 | Per-device cookie limit | | `PAIRING_CODE_LENGTH` | 6 digits | Pairing code size | | `PAIRING_TTL_MS` | 5 minutes | Pairing session expiry | | `NONCE_BYTES` | 24 | XChaCha20 nonce size | | `PING_INTERVAL_MS` | 30 seconds | WebSocket keepalive | | `PONG_TIMEOUT_MS` | 10 seconds | Pong deadline | | `POLL_INTERVAL_MS` | 5 seconds | HTTP polling default |