Sync protocol¶
Voltius follows a Zero-Knowledge protocol for every sync path. All data leaving your device is strictly ciphertext — the auth server, the SSE relay, and GitHub all have zero knowledge of your vault contents.
Architecture¶
flowchart TD
classDef cleartext fill:#ffebee,stroke:#c62828,stroke-width:2px,color:#000;
classDef secure fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px,color:#000;
classDef local fill:#fff3e0,stroke:#e65100,stroke-width:2px,color:#000;
classDef remote fill:#e3f2fd,stroke:#1565c0,stroke-width:2px,color:#000;
classDef wasm fill:#f3e5f5,stroke:#6a1b9a,stroke-width:2px,color:#000;
classDef note fill:#f9f9f9,stroke:#666,stroke-width:1px,stroke-dasharray: 5 5,color:#333;
subgraph RegLayer ["0. Account Creation (one-time)"]
direction LR
subgraph PortalReg ["Web Portal — app.voltius.app"]
PortalCreds["Email + Password"]:::cleartext
WasmKDF["voltius-crypto-wasm\n(Argon2id + HKDF-SHA256\nsame crate · WASM target)"]:::wasm
AuthKeyPortal(("auth_key")):::secure
PortalCreds -->|"password + generated account_id"| WasmKDF
WasmKDF -->|"enc_key discarded\n(no vault in portal)"| WasmKDF
WasmKDF --> AuthKeyPortal
end
subgraph DesktopReg ["Desktop Client (Tauri)"]
DesktopCreds["Email + Password"]:::cleartext
NativeKDF["voltius-crypto · native Rust\n(Argon2id + HKDF-SHA256)"]:::secure
AuthKeyDesktop(("auth_key")):::secure
DesktopCreds -->|"password + generated account_id"| NativeKDF
NativeKDF -->|"enc_key → vault unlock\n(proceeds to step 1)"| NativeKDF
NativeKDF --> AuthKeyDesktop
end
RegServer[("Auth Server")]:::remote
AuthKeyPortal -->|"email + auth_key + account_id"| RegServer
AuthKeyDesktop -->|"email + auth_key + account_id\n+ public_key + machine_fingerprint"| RegServer
RegServer -->|"JWT + account_id"| PortalCreds
RegServer -->|"JWT + account_id"| DesktopCreds
end
subgraph AuthLayer ["1. Vault Unlock (Tauri Desktop — voltius-crypto · native Rust)"]
direction TB
subgraph Methods ["Vault Unlock Methods"]
direction LR
OS["OS Keychain"]:::local
MP["Master Password"]:::local
Cloud["Cloud Account\n(Email & Password)"]:::remote
end
KDF["Argon2id + HKDF-SHA256\n(32 MB mem · 2 iters)"]:::secure
EncKey(("enc_key\n(AES-256-GCM key)")):::secure
AuthKey(("auth_key\n→ server login")):::secure
Cloud -->|"password + account_id"| KDF
MP -->|"password + account_id"| KDF
OS -->|"retrieves enc_key directly\n(stored after prior login)"| EncKey
KDF --> EncKey
KDF --> AuthKey
AuthKey -->|"POST /v1/auth/login"| AuthServer[("Auth Server")]:::remote
AuthServer -->|"JWT"| Cloud
end
RegLayer -.->|"account created — use same\ncredentials in desktop Cloud Account"| Cloud
subgraph VaultLayer ["2. Local Vault (Rust · aes-gcm crate)"]
AesGcm{"AES-256-GCM\n(Rust, via Tauri IPC)"}:::secure
LocalStore[("secrets.enc\n(disk)")]:::local
AesGcm <==>|"encrypt / decrypt"| LocalStore
end
EncKey -->|"enc_key passed over Tauri IPC"| AesGcm
subgraph SyncLayer ["3. Zero-Knowledge Remote Sync"]
direction LR
subgraph GistSync ["Gist Sync (free · polling)"]
direction TB
GistKDF["derive_gist_key (Tauri cmd)\nArgon2id + HKDF-SHA256\npassphrase/PAT + manifest salt"]:::secure
GistAes{"AES-256-GCM\n(Rust)"}:::secure
Gist[("GitHub Gists\n(Bring-Your-Own)")]:::remote
GistKDF -->|"gist_enc_key"| GistAes
GistAes <==>|"Encrypted CRDT blobs"| Gist
end
subgraph CloudSync ["Cloud Sync (Pro/Teams · SSE)"]
direction TB
SseAes{"AES-256-GCM\n(Rust · encrypt_payload)"}:::secure
SSE[("Voltius SSE Server")]:::remote
SseAes <==>|"Encrypted CRDT payloads"| SSE
end
end
EncKey -->|"enc_key"| SseAes
Layers explained¶
0. Account creation¶
A one-time step. Both the web portal and desktop client derive an auth_key from your email + password using Argon2id + HKDF-SHA256. The portal discards the enc_key (it has no vault); the desktop client keeps it for vault unlock.
1. Vault unlock¶
The desktop client unlocks your local vault via one of three methods:
- OS Keychain — retrieves
enc_keydirectly from your system's secure storage. - Master Password — re-derives
enc_keyvia Argon2id (32 MB mem, 2 iters) + HKDF-SHA256. - Cloud Account — same derivation, plus posts
auth_keyto the auth server to receive a JWT.
2. Local vault¶
Secrets are stored on disk in secrets.enc, encrypted with AES-256-GCM via the aes-gcm Rust crate. The enc_key never leaves the Tauri Rust process.
3. Remote sync¶
Two zero-knowledge transports:
- Gist Sync (free) — encrypted CRDT blobs polled to/from your private GitHub Gist using a separately-derived
gist_enc_key. - Cloud Sync (Pro/Teams) — encrypted CRDT payloads over SSE to the Voltius relay server.
What the server never sees
Your password, your enc_key, your decrypted vault, or any plaintext connection metadata. The server only sees an opaque auth_key for login and ciphertext for sync.