Skip to main content

max / synckit-client

git clone https://makenot.work/git/max/synckit-client.git git clone git@ssh.makenot.work:max/synckit-client.git
Name Size
/ docs/
/ src/
/ tests/
· .gitignore 86 B
· Cargo.lock 58.9 KB
· Cargo.toml 984 B
· LICENSE 4.4 KB
· README.md 3.0 KB

README

synckit-client

End-to-end encrypted cloud sync SDK for Rust applications, built for the MNW SyncKit server.

All row data and binary blobs are encrypted client-side (XChaCha20-Poly1305) before leaving the device. The server only ever stores ciphertext.

Features

  • E2E encryption – XChaCha20-Poly1305 with Argon2id key derivation (64 MB, 3 iterations)
  • OS keychain integration – master key cached in macOS Keychain, Linux secret-service, or Windows Credential Manager
  • Blob encryption – binary files encrypted with fixed 40-byte overhead (no base64 expansion)
  • Retry with backoff – transient failures (network, 5xx, 429) retried up to 3 times with exponential delay
  • OAuth2 PKCE – browser-based auth flow alongside email/password
  • Token expiry detection – client-side JWT check with 30-second buffer

Quick Start

use synckit_client::{SyncKitClient, SyncKitConfig, ChangeEntry, ChangeOp};
use chrono::Utc;

let client = SyncKitClient::new(SyncKitConfig {
    server_url: "https://makenot.work".into(),
    api_key: "your-api-key".into(),
});

// Authenticate
let (user_id, app_id) = client.authenticate("user@example.com", "password").await?;

// Set up encryption (first device)
client.setup_encryption_new("password").await?;

// Register this device
let device = client.register_device("MacBook Pro", "macos").await?;

// Push encrypted data
let cursor = client.push(device.id, vec![
    ChangeEntry {
        table: "tasks".into(),
        op: ChangeOp::Insert,
        row_id: uuid::Uuid::new_v4().to_string(),
        timestamp: Utc::now(),
        data: Some(serde_json::json!({"title": "Buy milk"})),
    },
]).await?;

// Pull and auto-decrypt
let (changes, cursor, has_more) = client.pull(device.id, 0).await?;

Crate Structure

FileRole
lib.rsCrate root, re-exports, doc example
client.rsSyncKitClient – HTTP methods, retry logic, token expiry detection
crypto.rsKey derivation (Argon2id), key wrapping, per-entry and per-blob encrypt/decrypt
error.rsSyncKitError enum (10 variants: HTTP, server, JSON, crypto, keychain, auth)
keystore.rsOS keychain read/write/delete, feature-gated with no-op stubs
types.rsWire protocol types (ChangeEntry, ChangeOp, Device, SyncStatus)

Feature Flags

FlagDefaultDescription
keychainonOS keychain storage via the keyring crate. Disable with default-features = false for headless/CI environments.

Security Properties

  • Server-zero-knowledge – the server never receives the plaintext master key or user data
  • Key zeroization – volatile writes clear the master key from memory on drop
  • Random salt per wrap – re-wrapping with the same password produces a different envelope
  • Minimum ciphertext validation – decryption rejects inputs shorter than 40 bytes (24-byte nonce + 16-byte tag)
  • No key material in logs – tracing events never include key bytes or ciphertext

License

PolyForm Noncommercial 1.0.0