# tsafe-collab
Team collaboration service skeleton for [tsafe](https://crates.io/crates/tsafe-cli).
Provides the `CollabRemote` trait and an in-memory stub server for sharing
encrypted vault DEKs (data encryption keys) between team members using
age encryption + Shamir secret sharing for recovery.
## Status: Early / Experimental
The collaboration service protocol and wire format are defined; production
server infrastructure is not yet included. The stub server (for testing) is.
## Key types
- `CollabRemote` — trait for membership directory, DEK delivery, invite flow,
and recovery-share transport; synchronous HTTP via `ureq` for production
implementations
- `StubServer` — thread-safe in-memory `CollabRemote` implementation backed
by `HashMap` state; enforces the membership gate on every call
- `MemberEntry` — team member identified by an age X25519 bech32 public key
- `DekEnvelope` — age-encrypted DEK blob; the server stores it opaquely and
cannot decrypt it (`schema: "tsafe/collab-dek/v1"`)
- `InviteToken` / `InviteRecord` — TOFU-bound invite flow (ADR-028): an invite
is bound to a specific invitee pubkey at creation time; `confirm_invite`
enforces the binding and consumes the token (one-use, 48-hour TTL)
- `split_recovery_key` / `reconstruct_recovery_key` — Shamir N-of-M sharing
## Wire format
Recovery shares produced by `split_recovery_key` are serialized as:
```
[ threshold: u8 ][ blahaj_share_bytes: x || y[0..31] ]
```
The leading threshold byte lets `reconstruct_recovery_key` operate without
the caller tracking the threshold separately. Total per-share size: 33 bytes.
Base64-encode for transport. See `docs/decisions/shamir-crate-selection.md`
(ADR-032) for crate-selection rationale (`blahaj 0.6` as the maintained
successor to `sharks 0.5`).
## Architectural boundary
`tsafe-core` MUST NOT import this crate (ADR-027). The dependency direction is:
```
tsafe-collab → (ureq, age, serde, thiserror, uuid, chrono, blahaj)
tsafe-cli → tsafe-collab [feature = "collab"]
```
Add `--features collab` to the CLI build to pull this crate in. The crate
compiles and all tests pass without a live collab-service.
## Security properties
- The server (stub or production) stores only age-encrypted ciphertext — it
holds no plaintext key material (ADR-027 "Service NEVER holds").
- DEK envelopes are age-encrypted to the recipient's X25519 public key;
a non-member who obtains the envelope bytes cannot decrypt them.
- `fetch_dek` and `fetch_recovery_share` enforce membership before returning
any data; the adversarial proof is in
`tests/non_member_dek_isolation.rs` (D3.4).