Skip to main content

max / synckit

4.9 KB · 124 lines History Blame Raw
1 [package]
2 name = "synckit-client"
3 version = "0.6.0"
4 edition = "2024"
5 description = "SyncKit client SDK with end-to-end encryption"
6 license-file = "LICENSE"
7
8 [features]
9 default = ["keychain", "store"]
10 keychain = ["dep:keyring"]
11 # The higher-level SyncStore engine (owns a rusqlite connection to the app's DB).
12 # Default-on so app consumers get it for free; a consumer that only needs the
13 # transport/crypto SDK (e.g. mnw-cli, which sets `default-features = false`) skips
14 # it and avoids compiling bundled SQLite.
15 store = ["dep:rusqlite", "dep:synckit-config"]
16 # Exposes test-only constructors (`set_master_key_raw`, `with_http_client`) that
17 # bypass key derivation. Enabled automatically for this crate's own test builds
18 # via the self dev-dependency below; never part of `default`, so a real consumer
19 # cannot reach a raw-key injection point.
20 testing = []
21
22 [dependencies]
23 # Encryption
24 chacha20poly1305 = "0.11"
25 argon2 = "0.5"
26 rand = "0.10"
27 base64 = "0.22"
28 zeroize = "1"
29 # X25519 ECDH — the only asymmetric primitive in the crate, used solely by the
30 # group-key layer (`identity.rs`) to seal a Group Content Key to a member's public
31 # key. Pure-Rust (curve25519-dalek), no aws-lc/ring. Deliberately just the curve op:
32 # the GCK itself is sealed with the XChaCha20-Poly1305 above, not a sealed-box crate.
33 # `static_secrets` enables the reusable `StaticSecret` (a member's long-lived key).
34 x25519-dalek = { version = "2", default-features = false, features = ["static_secrets", "zeroize"] }
35
36 # PKCE (OAuth2) challenge hashing
37 sha2 = "0.11"
38 hex = "0.4"
39
40 # HTTP
41 # rustls-no-provider: rustls TLS with the OS-native trust store (rustls-platform-verifier),
42 # no bundled crypto provider — the consuming app installs one process default (ring).
43 reqwest = { version = "0.13", default-features = false, features = ["json", "rustls-no-provider", "stream", "form", "charset", "http2", "system-proxy"] }
44 bytes = "1"
45 tokio = { version = "1", features = ["rt-multi-thread", "macros", "time", "fs", "io-util"] }
46 tokio-stream = "0.1"
47
48 # Serialization
49 serde = { version = "1", features = ["derive"] }
50 serde_json = "1"
51 chrono = { version = "0.4", features = ["serde"] }
52 uuid = { version = "1", features = ["v4", "serde"] }
53
54 # OS keychain (optional)
55 keyring = { version = "4", optional = true }
56
57 # URL encoding
58 urlencoding = "2"
59
60 # Unicode
61 unicode-normalization = "0.1"
62
63 # Synchronization
64 parking_lot = "0.12"
65
66 # Error handling & logging
67 thiserror = "2"
68 tracing = "0.1"
69
70 # SyncStore engine (feature = "store"). Owns the app's SQLite connection. Bundled
71 # so no system libsqlite is needed; `functions` to register the `hash_row_id` UDF.
72 rusqlite = { version = "0.39", features = ["bundled", "functions"], optional = true }
73 # The local config store (posture types + KV store). The config sync adapter
74 # (src/store/config.rs) turns a ConfigSpec into a SyncTable. Path dep: sibling in
75 # the MNW tree, versioned together.
76 synckit-config = { path = "../synckit-config", optional = true }
77
78 [dev-dependencies]
79 wiremock = "0.6"
80 # reqwest is built `rustls-no-provider`, so real consumers install a rustls crypto
81 # provider at startup (audiofiles installs ring). The test suite has no such app, so
82 # it installs ring itself before building any client. Dev-only: never in a consumer build.
83 rustls = { version = "0.23", default-features = false, features = ["ring"] }
84 # Self dev-dependency: turns on the `testing` feature for this crate's own
85 # unit/integration test builds without leaking it into a consumer's default set.
86 # `default-features = false` so it only ADDS `testing` to whatever the test run
87 # already selected — under a plain `cargo test` the package still builds with its
88 # own defaults (keychain + store), but `cargo test --no-default-features` can turn
89 # keychain OFF (making `keystore::store_key` the no-op stub) to run the keychain-
90 # free rotation orchestration test below.
91 synckit-client = { path = ".", default-features = false, features = ["testing"] }
92
93 [lints.rust]
94 unused = "warn"
95 unreachable_pub = "warn"
96
97 [lints.clippy]
98 pedantic = { level = "warn", priority = -1 }
99 # Allow-list tuned from a measured breakdown across server/multithreaded/pter
100 # (2026-07-22). These are the high-churn / low-signal pedantic lints; everything
101 # else in `pedantic` stays a warning. Keep this block identical across repos.
102 module_name_repetitions = "allow"
103 # Doc lints. No docs-completeness push is underway.
104 missing_errors_doc = "allow"
105 missing_panics_doc = "allow"
106 doc_markdown = "allow"
107 # Numeric casts. Endemic and mostly intentional in size and byte math.
108 cast_possible_truncation = "allow"
109 cast_sign_loss = "allow"
110 cast_precision_loss = "allow"
111 cast_possible_wrap = "allow"
112 cast_lossless = "allow"
113 # Subjective structure and style nags. High churn, low signal.
114 must_use_candidate = "allow"
115 too_many_lines = "allow"
116 struct_excessive_bools = "allow"
117 similar_names = "allow"
118 items_after_statements = "allow"
119 single_match_else = "allow"
120 # Frequent false-positives in TUI and router-heavy code.
121 match_same_arms = "allow"
122 unnecessary_wraps = "allow"
123 type_complexity = "allow"
124