| 6 |
6 |
|
|
| 7 |
7 |
|
## Features
|
| 8 |
8 |
|
|
| 9 |
|
- |
- **E2E encryption** -- XChaCha20-Poly1305 with Argon2id key derivation (64 MB, 3 iterations)
|
| 10 |
|
- |
- **OS keychain integration** -- master key cached in macOS Keychain, Linux secret-service, or Windows Credential Manager
|
| 11 |
|
- |
- **Blob encryption** -- binary files encrypted with fixed 40-byte overhead (no base64 expansion)
|
| 12 |
|
- |
- **Retry with backoff** -- transient failures (network, 5xx, 429) retried up to 3 times with exponential delay
|
| 13 |
|
- |
- **OAuth2 PKCE** -- browser-based auth flow alongside email/password
|
| 14 |
|
- |
- **Token expiry detection** -- client-side JWT check with 30-second buffer
|
|
9 |
+ |
- **E2E encryption**: XChaCha20-Poly1305 with Argon2id key derivation (64 MB, 3 iterations)
|
|
10 |
+ |
- **OS keychain integration**: master key cached in macOS Keychain, Linux secret-service, or Windows Credential Manager
|
|
11 |
+ |
- **Blob encryption**: binary files encrypted with fixed 40-byte overhead (no base64 expansion)
|
|
12 |
+ |
- **Retry with backoff**: transient failures (network, 5xx, 429) retried up to 3 times with exponential delay
|
|
13 |
+ |
- **OAuth2 PKCE**: browser-based auth flow alongside email/password
|
|
14 |
+ |
- **Token expiry detection**: client-side JWT check with 30-second buffer
|
| 15 |
15 |
|
|
| 16 |
16 |
|
## Quick Start
|
| 17 |
17 |
|
|
| 51 |
51 |
|
|
| 52 |
52 |
|
## Crate Structure
|
| 53 |
53 |
|
|
| 54 |
|
- |
| File | Role |
|
|
54 |
+ |
Two layers. `client/` is the HTTP transport and encryption boundary; `store/` is the
|
|
55 |
+ |
higher-level engine that absorbs the SQLite plumbing a consuming app would otherwise
|
|
56 |
+ |
write itself. An app can use either.
|
|
57 |
+ |
|
|
58 |
+ |
| Path | Role |
|
| 55 |
59 |
|
|------|------|
|
| 56 |
60 |
|
| `lib.rs` | Crate root, re-exports, doc example |
|
| 57 |
|
- |
| `client.rs` | `SyncKitClient` -- HTTP methods, retry logic, token expiry detection |
|
|
61 |
+ |
| `client/` | `SyncKitClient`: HTTP transport and the high-level API, with transparent end-to-end encryption. Split across `auth`, `blob`, `encryption`, `groups`, `helpers`, `ota`, `rotation`, `subscribe`, `subscription`, `sync` |
|
|
62 |
+ |
| `store/` | `SyncStore`, the syncable-store engine: `apply`, `blob`, `config`, `db`, `facade`, `hlc`, `migrate`, `scheduler`, `schema`, `sync` |
|
| 58 |
63 |
|
| `crypto.rs` | Key derivation (Argon2id), key wrapping, per-entry and per-blob encrypt/decrypt |
|
| 59 |
|
- |
| `error.rs` | `SyncKitError` enum (10 variants: HTTP, server, JSON, crypto, keychain, auth) |
|
|
64 |
+ |
| `identity.rs` | Group identity keys and Group Content Key grants, the crate's one asymmetric layer |
|
|
65 |
+ |
| `conflict.rs` | Client-side conflict detection and resolution |
|
|
66 |
+ |
| `oauth.rs` | OAuth2 PKCE helpers (RFC 7636, S256) for the MNW authorize/token flow |
|
| 60 |
67 |
|
| `keystore.rs` | OS keychain read/write/delete, feature-gated with no-op stubs |
|
|
68 |
+ |
| `ids.rs` | Strongly-typed identifier newtypes over `Uuid` |
|
|
69 |
+ |
| `error.rs` | `SyncKitError` enum (HTTP, server, JSON, crypto, keychain, auth) |
|
| 61 |
70 |
|
| `types.rs` | Wire protocol types (`ChangeEntry`, `ChangeOp`, `Device`, `SyncStatus`) |
|
| 62 |
71 |
|
|
| 63 |
72 |
|
## Feature Flags
|
| 68 |
77 |
|
|
| 69 |
78 |
|
## Security Properties
|
| 70 |
79 |
|
|
| 71 |
|
- |
- **Server-zero-knowledge** -- the server never receives the plaintext master key or user data
|
| 72 |
|
- |
- **Key zeroization** -- volatile writes clear the master key from memory on drop
|
| 73 |
|
- |
- **Random salt per wrap** -- re-wrapping with the same password produces a different envelope
|
| 74 |
|
- |
- **Minimum ciphertext validation** -- decryption rejects inputs shorter than 40 bytes (24-byte nonce + 16-byte tag)
|
| 75 |
|
- |
- **No key material in logs** -- tracing events never include key bytes or ciphertext
|
|
80 |
+ |
- **Server-zero-knowledge**: the server never receives the plaintext master key or user data
|
|
81 |
+ |
- **Key zeroization**: volatile writes clear the master key from memory on drop
|
|
82 |
+ |
- **Random salt per wrap**: re-wrapping with the same password produces a different envelope
|
|
83 |
+ |
- **Minimum ciphertext validation**: decryption rejects inputs shorter than 40 bytes (24-byte nonce + 16-byte tag)
|
|
84 |
+ |
- **No key material in logs**: tracing events never include key bytes or ciphertext
|
| 76 |
85 |
|
|
| 77 |
86 |
|
## License
|
| 78 |
87 |
|
|