Skip to main content

Groups

Groups are shared data contexts. Records created in a group can synchronize between its members' devices without exposing the member's personal data context.

Creating a group generates a signing key and an encryption key, stores the public keys on the signed Groups record, and stores the secret key as an encrypted personal persistent variable. Peers validates that a stored group secret derives the public keys on the group record before using it. A mismatched or malformed key is rejected instead of being used to encrypt new group data.

The founder also gets an explicit, signed GroupMembers row with the Founder role in the group context, so approvals and role checks see the same membership data joiners will receive. Groups created before this row existed are repaired the first time the founder approves a join.

Targeted device messages use the target user's public key from the shared group's Users and Devices records. This lets devices owned by different users exchange signaling and administration messages without depending on the sender's local copy of the group secret. Messages encrypted to the whole group continue to require matching group key material.

On receipt, Peers first verifies that the declared context is the device's personal context or an enabled Groups record. It then resolves the sender's Devices and Users records only inside that exact context and requires both the box and signature keys to match. Missing or conflicting identities fail before a device handler runs; stale personal records cannot override the identity recorded in the declared shared group.

Joining a group​

Open Identity → Groups. The list summarizes each group's description, member count, and your role. Create group in the persistent Identity action bar asks for a name. Use invite opens the same paste-or-scan screen used for contact invites.

Members join through invites. Inbound group invites and join requests appear in Identity → Activity. The Groups section badge counts only requests that need your decision; requests waiting on someone else do not create false urgency. An Admin or Owner opens the group's Members screen and uses Invite people:

  • Contacts — pick one or more existing contacts and a role. Each contact receives a ready-to-accept invite; nothing needs to be copied or scanned.
  • Share a link — issue a link/QR with a role and a mode: I approve each join (people request, you approve) or Anyone with the link joins (auto-admit while the link is valid). Pending requests and outstanding links are in Activity, filtered to this group.

Whichever path is used, admission is a signed group approval produced by the approving Admin or Owner's device:

  • The approver writes a signed GroupMembers row and weak Users/Devices stubs for the joiner in the group context.
  • The joiner receives the group record, Admin+ seed memberships, their own signed membership, the approver's identity, and the group encryption secret boxed to the joiner's key. Personal Groups is added only when it is missing; an existing personal row is left in place so a local disable or leave stays authoritative.
  • After import, the joiner opens a targeted connection to the approver in that group context. Signaling encrypts to the approver's user box key, so the group secret is not required for this first hop.

The group secret is validated against the signed group record before it is stored as a personal persistent variable, so a joiner can read and write group data as soon as the approval is imported. A member can only approve a role at or below their own.

From the CLI: peers groups invite <groupId> <userId>, peers groups invite <groupId> --link, and peers groups join <token>. See CLI.

Display names​

The signed connection handshake can include optional user and device display-name hints. Each hint is limited to 128 characters. They are presentation metadata, not identity: device and user IDs plus the signing keys remain authoritative.

The user hint fills the brief gap before the owner's signed Users row reaches a group. That signed row remains canonical and owner profile changes are copied from the owner's personal context into each group. The device hint is stored as reportedName on the existing Devices row and synchronizes with the group.

A device record's name is the local user's label, while reportedName is the latest label advertised by the device owner. Interfaces prefer name and fall back to reportedName, so another user's handshake cannot replace a local label. Updated hints arrive on the next connection handshake; they are intentionally not included in the more frequently exchanged network information.

Diagnosing group connectivity​

The desktop Network Viewer shows direct connections and shared-group routes. Owners can also use the CLI to inspect a directly connected device:

peers devices
peers devices status <deviceId>
peers db query "SELECT * FROM Groups" --device <deviceId> --json
peers db query "SELECT * FROM Devices" --context <groupId> --device <deviceId> --json

See Network diagnostics for authorization requirements, query limits, and the records to compare when a device is visible but signaling fails.