Source: https://docs.any.org/collaboration/index.html # Collaboration A space is the unit of sharing: one encrypted CRDT world with its own access-control list. Everything on these pages is about who is in a space, how they got there, what they may do, and how several devices or members converge on the same objects without a coordinator deciding for them. ## Four ways in - **A team space:** create an invite, the newcomer requests to join, an owner approves — [Invites](https://docs.any.org/collaboration/invites.md.txt). - **A known account:** grant its identity through the ACL; the recipient accepts the incoming space before loading it — [Access control](https://docs.any.org/collaboration/acl.md.txt). - **Two people:** the deterministic one-to-one derivation, no invite at all — [One-to-one spaces](https://docs.any.org/collaboration/one-to-one.md.txt). - **Readers without approval:** a guest key, read-only for anyone holding it — [Guest access](https://docs.any.org/collaboration/invites.md.txt). A successful join request means approval is pending, not that the space is ready to query: read membership and space status before showing shared data. ## The model in one picture ``` owner ── mints invite ──► token ──► joiner: POST /v1/spaces/join (status: joining) │ │ └── acl/accept {requestRecordId, permission} ─┘ ──► member (status: active) owner ── acl/add {identity, permission} ──► added account sees invite_pending ──► invite/accept me ── one-to-one {otherIdentity} ──► both derive the same space, both writers ``` | Concept | What it is | Page | | --- | --- | --- | | Member | an identity on a space's ACL with a `permission` and a `status` | [Members and roles](https://docs.any.org/collaboration/members-and-roles.md.txt) | | Invite | a shareable token that lets someone request to join, or a public read-only guest key | [Invites](https://docs.any.org/collaboration/invites.md.txt) | | ACL operation | owner/admin actions: accept, decline, change permissions, remove, add by identity, transfer ownership, stop sharing | [ACL](https://docs.any.org/collaboration/acl.md.txt) | | One-to-one space | a two-identity space derived from both account keys — no invite, no owner | [One-to-one](https://docs.any.org/collaboration/one-to-one.md.txt) | | Derived space | a well-known per-account space every device resolves to the same id | [Derived spaces](https://docs.any.org/collaboration/derived-spaces.md.txt) | | Bundle | one root object per install registered in the space, so members converge on one chat, one setup; the server's usecase catalog installs the well-known apps | [Bundles](https://docs.any.org/collaboration/bundles.md.txt) | ## Roles | Permission | Can | | --- | --- | | `owner` | everything, including ACL operations and ownership transfer | | `admin` | manage members | | `writer` | read and write content | | `reader` | read content | | `guest` | read-only via a shared public guest key; writes return `403 space.read_only` | | `none` | no access (also "not mirrored yet" on `SpaceInfo.ownRole`) | Your own role in every space is mirrored onto the space list as `SpaceInfo.ownRole`, so a UI can gate role-dependent controls straight from `GET /v1/spaces` — no per-space fan-out. `GET /v1/spaces/:id/members/me` is the authoritative read when it matters. > **Why it matters.** Access control is cryptographic, not a policy a server enforces: a grant hands the member the space's read key, a removal rotates it for every change from then on (what the member already received stays decryptable). A relay that stores the space cannot read it, and cannot quietly add itself as a member. ## Convergence without a coordinator Two themes recur across the section: - **Derive instead of create** when several parties must land on the same object. A one-to-one space id is a function of both account keys; a derived space id is a function of the account keys and a fixed seed; a bundle root can be derived from its bundle id. Nothing to race, nothing to reconcile. - **Approval is local when the cryptography cannot gate it.** A one-to-one ACL is immutable and a direct-add already puts you on the ACL, so "accept" governs whether *this device materializes the space*, surfaced as a space `status`, not an ACL write. [**Members and roles** — The authoritative per-space roster, permission and status strings, live member events.](https://docs.any.org/collaboration/members-and-roles.md.txt) [**Invites** — Mint, list and revoke invite tokens; request-to-join; public guest keys.](https://docs.any.org/collaboration/invites.md.txt) [**ACL** — Accept, decline, change permissions, remove, add by identity, transfer ownership, stop sharing.](https://docs.any.org/collaboration/acl.md.txt) [**One-to-one** — Direct spaces derived from two identities, with the pending/declined state machine.](https://docs.any.org/collaboration/one-to-one.md.txt) [**Derived spaces** — Well-known per-account spaces every device converges on; permanent by design.](https://docs.any.org/collaboration/derived-spaces.md.txt) [**Bundles** — Adopt-or-install roots, derived roots, losers and resolve, the usecase catalog and the general chat.](https://docs.any.org/collaboration/bundles.md.txt)