Concepts
Member, device, graph
Section titled “Member, device, graph”| term | means |
|---|---|
| member | a person or account, as your identity system names them |
| device | one installation. Holds keys. Registered with a public key, set-once. |
| graph | a keyed namespace of records. Three shapes: u, g:<id>, d:<id>. |
| record | {id, kind, data, at, by}. at is both timestamp and revision. |
| epoch | a generation of a graph’s key. Rotation mints the next one. |
| keyring | epoch → key, on a device. Old epochs are kept so history stays readable. |
The three graph shapes
Section titled “The three graph shapes”await engine.openGraph('u'); // personal — only this member's devicesawait engine.openGraph('g:acme'); // shared — membership from your Directoryawait engine.openGraph('d:alex'); // pairwise with alex — its own keyuis per member. Preferences, read positions, private notes.g:<id>is any shared space: a team, a workspace, a project, a document with collaborators. Membership is whatever yourDirectorysays it is.d:<id>is a two-party channel. Sam addresses itd:alex; Alex addresses itd:sam; both land on the same key and the same storage slot.
Choosing a graph is choosing a key boundary. Everything in one graph is readable by everyone in that graph — role rules inside a graph are UI courtesy, not cryptography. If a distinction must hold cryptographically, use a separate graph.
Keys belong to devices
Section titled “Keys belong to devices”This is the single most important thing to understand about skm, and the thing that differs from most E2E systems.
No API hands you a private key. No ceremony moves one between machines. Adding a device is a grant: the new device publishes a public key, and any device that already holds the keyring wraps it over. Losing one device is revocable without touching the others.
The recovery bundle exists for when there is no device left to grant from, and it carries graph keys only — never a device keypair.