> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sovseal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Zero-Knowledge Team Collaboration in sovseal

> Share encrypted memory contexts across teammates using wrapped DEK grants — the server sees only public keys and opaque envelopes, never your plaintext DEK.

Sharing an encrypted memory context across multiple developers or AI agents is fundamentally a key-distribution problem. If you share the raw Data Encryption Key (DEK) through a server, you lose zero-knowledge guarantees the moment the server is compromised. sovseal solves this with **cryptographic envelope encryption**: each collaborator receives a copy of the project DEK wrapped (encrypted) to their own public key, so the server stores only opaque key-grant envelopes it can never open. When you revoke a member, the DEK itself rotates — not just the access record — ensuring the ex-member's cached copy cannot decrypt any future writes.

<Note>
  **Provenance Layer — Hybrid (Layer A + Layer B)** — Member lists, role metadata, and wrapped DEK envelopes are managed at Layer A (server-known). Key wrapping, unwrapping, and all plaintext DEK operations run at Layer B (client-derived, never leaves your device). The server sees public keys and opaque base64 blobs. It never sees your cleartext DEK, private key, or memory payloads.
</Note>

<Note>
  Teams & RBAC is available on the managed **Platform** only. Self-hosted deployments manage access at the infrastructure level and do not include the envelope-encryption collaboration model described here.
</Note>

## How the Envelope Encryption Model Works

Each shared project has a single DEK that encrypts and decrypts all memory envelopes. The DEK never travels to the server in plaintext. Instead, the system wraps it individually for each team member using their public key.

When a member needs to read memories, their browser downloads their personal wrapped-DEK grant from the `/grant` endpoint and unwraps it using their local private key — all in-browser, with no server involvement beyond serving the opaque blob.

This model has two important properties:

* **Additive grants** — inviting a new member only requires the inviter to wrap the existing DEK to the new member's public key and upload one new `key_grants` row. No re-encryption of existing memory envelopes is needed.
* **Revocation by rotation** — removing a member requires generating a fresh DEK and re-wrapping it for remaining members, because the server cannot revoke access to a DEK copy the ex-member already holds locally.

## Setting Up a Team

<Steps>
  <Step title="Create the project">
    In the console, create a new project or open an existing one. The project's DEK is generated locally in your browser and never transmitted to the server. Your own wrapped-DEK grant is created immediately and stored in `key_grants`.
  </Step>

  <Step title="Open Team Settings">
    Navigate to **Settings → Team** for the project. You will see your own entry listed as **Admin** with a key grant badge.
  </Step>

  <Step title="Invite a member">
    Click **Invite Member** and enter the invitee's email address. sovseal sends them an invitation link. When they accept, their client generates a local public/private keypair and registers the public key with the server.
  </Step>

  <Step title="Wrap and grant the DEK">
    Once the invitee's public key is registered, your browser automatically retrieves it from the server, wraps your project DEK with it using RSA-OAEP, and uploads the resulting envelope as a new `key_grants` row. The invitee can now load their grant, unwrap the DEK locally, and access the project's memory records.
  </Step>

  <Step title="Assign a role">
    Select the member's role — **Admin**, **Write**, or **Read** — from the role dropdown in the team table. Role assignments are enforced server-side for API requests and client-side for explorer access.
  </Step>
</Steps>

## Roles and Permissions

Operations are enforced at both the server API layer and the client explorer layer.

| Role      | Read memories                | Write memories | Manage members | Rotate DEK |
| --------- | ---------------------------- | -------------- | -------------- | ---------- |
| **Admin** | ✅                            | ✅              | ✅              | ✅          |
| **Write** | ✅                            | ✅              | ❌              | ❌          |
| **Read**  | ✅ (requires valid key grant) | ❌              | ❌              | ❌          |

A **Read** member without a valid key grant sees only ciphertext. The role itself does not grant decryption — the key grant does. This means you can grant Read role to a member before completing the key-wrapping step and they will have no access to plaintext content until the grant is uploaded.

## Revoking a Member

Removing a member from a project must invalidate their access to future writes. A simple database delete is insufficient — the ex-member would still hold the old DEK locally and could decrypt new envelopes written with it. sovseal enforces a four-step revocation protocol.

<Steps>
  <Step title="Delete the member grant">
    Click **Revoke** next to the member's entry in the Team table. This deletes their `key_grants` row and sets their `team_members` status to `inactive`. They immediately lose API access (server-enforced), but they still hold a locally cached copy of the old DEK.
  </Step>

  <Step title="Generate a fresh DEK">
    The admin's browser generates a new random AES-256-GCM DEK. This happens automatically as part of the revocation flow — you do not need to take a separate action.
  </Step>

  <Step title="Re-wrap for remaining members">
    The browser downloads the public keys of all remaining active members, wraps the new DEK to each public key, and uploads the updated `key_grants` entries. A new rotation epoch is recorded in `dek_rotations`.
  </Step>

  <Step title="Confirm rotation">
    The console displays a confirmation banner once all grants are re-uploaded. Any memory envelopes written after this point use the new DEK. The revoked member's cached key cannot decrypt them, even if they retained the raw ciphertexts from before revocation.
  </Step>
</Steps>

<Warning>
  During the re-wrapping step, your browser must be online and must hold the admin key for the project. If you navigate away before the rotation completes, remaining members may temporarily be unable to load their updated grants. The console will prompt you to resume the rotation on your next visit if it was interrupted.
</Warning>

## Per-Agent Sub-Keys

For autonomous AI agents or CI/CD pipelines that need write access without human authentication, admins can issue scoped `sov_live_` sub-keys bound to specific member grants.

* Each sub-key is individually labeled — for example, `agent-prod-writer` or `ci-test-runner`.
* Sub-keys carry the scopes you assign (`write:snapshots`, `read:snapshots`), not `admin`.
* Revoking a sub-key takes effect server-side in under 5 seconds, without requiring a DEK rotation (sub-keys authenticate at Layer A; they do not hold the DEK).
* Sub-key activity appears separately in the per-key audit log, so you can trace exactly which agent process made each write.

To issue a sub-key, open **Settings → API Keys**, click **Generate New Key**, and select the team member grant context you want it bound to.

## Key Recovery for Teams

On the **Growth** and **Pro** tiers, sovseal offers Shamir-split escrow for the project DEK, allowing recovery if the last admin loses their local private key. On the **Enterprise** tier, recovery is backed by HSM-based custody. **Hobby** and **Starter** tiers do not include key recovery and fail closed — losing your DEK means losing access to encrypted memories, by design.

For details on rotation policies and token management, see [API Keys](/platform/console/api-keys).
