XIP-82: External commit invites#138
Conversation
Shareable group invites enabling QR-code or link-based joins via atomic MLS External Commits with admin-controlled policy. Also adds HPKE, NAPI, and openmls to the cspell dictionary.
|
|
||
| ### Join-side flow | ||
|
|
||
| A non-member with an `ExternalInvitePayload` and an `EncryptedGroupInfoBlob` performs the following: |
There was a problem hiding this comment.
🟠 High XIPs/xip-82-external-commit-invites.md:389
Step 5 in the Join-side flow says to verify EXTERNAL_COMMIT_POLICY.external_group_id == payload.external_group_id "after the commit lands," but the commit is not built until step 7 or published until step 8. An implementer following these steps sequentially would attempt to read group state before joining. Step 5 should be moved after step 8 (and before step 9) when the joiner actually has group state to read.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file XIPs/xip-82-external-commit-invites.md around line 389:
Step 5 in the Join-side flow says to verify `EXTERNAL_COMMIT_POLICY.external_group_id == payload.external_group_id` "after the commit lands," but the commit is not built until step 7 or published until step 8. An implementer following these steps sequentially would attempt to read group state before joining. Step 5 should be moved after step 8 (and before step 9) when the joiner actually has group state to read.
ApprovabilityVerdict: Needs human review 1 blocking correctness issue found. This PR adds a new XIP specification document to a directory owned by @jhaaaa, and the author is not the designated owner. New protocol specifications should be reviewed by the designated CODEOWNER. There is also an unresolved comment about step sequencing in the specification that needs attention. You can customize Macroscope's approvability policy. Learn more. |
Summary
Introduces External Commit Invites: a shareable invite token (QR / link / NFC) that lets a non-member join an XMTP group on their own via an atomic MLS External Commit (RFC 9420 §12.4.3.2), without any existing member being online at scan time.
The mechanism is a two-piece design:
ExternalInvitePayload— small shareable capability (key + service slot id + opaque service pointer). What's encoded in the QR.EncryptedGroupInfoBlob— large encrypted MLS state held by an out-of-band service. Carries plaintextepoch+group_state_hashso the service can totally-order uploads by epoch and reject equal-epoch forks without ever seeing decrypted GroupInfo.Admin control lives in a new well-known AppData component:
EXTERNAL_COMMIT_POLICY— runtime-toggleable master switch plus the active invite'ssymmetric_keyandexternal_group_id. Storing the key in group state is what lets a printed QR survive epochs — any just-joined member can re-export and re-upload under the same key without the issuing admin being online.Per-component declarative authorization for external committers lives in a new field on
ComponentMetadata:ComponentMetadata.external_committer_permissions— symmetric twin of the existingpermissionsfield, evaluated against external commits. Absent = all-Deny.Lifecycle invariants spelled out in the spec: enable must atomically populate the invite coordinates, revoke must atomically clear them, re-enable must use fresh material (no key revival).
Discussion
I've raised the design with the team in #review-napkin over the past week. Key decisions captured in the Rationale and "Alternatives considered" sections:
external_group_id(≥4 bytes, 16 random RECOMMENDED) — not a hash of the group_id. AEAD already prevents the swap-ciphertext attack.Reference implementation
libxmtp PR stack (open):
MlsGroup::create_external_invite+Client::join_group_by_external_inviteProto: xmtp/proto#333 (generic intent), xmtp/proto#334 (this XIP's wire format).
openmls: upstream PR in flight; XMTP fork carries the patch.
Test plan
cspellagainst the repo dictionary).🤖 Generated with Claude Code
Note
Add XIP-82 spec for External Commit Invites via QR/link-based MLS flow
Adds xip-82-external-commit-invites.md, a new XMTP Improvement Proposal defining a QR/link-based MLS External Commit invite flow.
ExternalInvitePayloadandEncryptedGroupInfoBlob, using HPKE for encryptionEXTERNAL_COMMIT_POLICYAppData component with field-coupling invariants and per-componentexternal_committer_permissionsHPKE,NAPI, andopenmlsto the spell-check dictionary in cspell.json📊 Macroscope summarized 1ac135e. 2 files reviewed, 1 issue evaluated, 0 issues filtered, 1 comment posted
🗂️ Filtered Issues