feat(manager): issue in a room's name — invitation, membership, authority - #207
Merged
Conversation
…rity The owner surface the console was missing, and the half of it that works today: all three tasks terminate at the operator's own VTA, so unlike `rooms/create` they are reachable from a browser. Three verbs rather than one, because the membership model has three ideas in it. An invitation is consent — without it an owner seals a room key to somebody's agent and they are simply in, holding keys to material they may not want, having agreed to nothing. A membership credential is what a member presents afterwards, and does not collapse into the invitation: a VIC names its subject, so presenting one per access would disclose the member to the host on every read. An authority credential is what they may do; a room can admit someone who may only read. The screen keeps the credential until it is dismissed, and says why. Nothing else holds a copy — the agent signs and keeps no record, because a room's membership lives in its credentials rather than in a roster any one party keeps — so a result that faded would destroy it. That is invariant I1 working as intended and it has a cost worth stating on screen: the owner is the only party who knows what they have issued. Two things the words have to carry, because neither is visible in the verb: an invitation with no expiry is a standing right to enter held by whoever ends up with the bytes (single-use bounds how many it admits, not how long it keeps admitting one), and `admin` mints epochs — which is how a member is removed, so a party holding it can remove any other. The signing key is typed in rather than derived. Nothing maps a room's DID to the key it was minted with, and a surface that guessed would mint credentials that fail to verify against the room's own document. Signed-off-by: Glenn Gore <glenn.g@affinidi.com>
🛡️ AI Agentic Security Code Review🔎 A manual security review is recommended before merging. Please contact the Security team for specifics and remediation guidance.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The owner surface the console was missing — and specifically the half that works today: all three tasks terminate at the operator's own VTA, so unlike
rooms/createthey are reachable from a browser. (See #206 for why that distinction exists.)Three verbs, because the membership model has three ideas in it
privateroom with nobody outside able to tell them they are there. Single-use, consumed on entry.Each is a separate task URI, and the tests assert that directly — sending an invitation where a membership was asked for admits somebody once and leaves them unable to present afterwards.
The credential is the only copy, and the screen says so
The agent signs and keeps no record of having issued, because a room's membership and authority live in the credentials themselves and a list kept at the agent would be the roster the whole design keeps away from any single party.
So the result stays on screen until dismissed rather than appearing as a toast — a notification that fades is a credential destroyed. The copy says plainly that nothing else holds one.
That is invariant I1 working as intended rather than a gap: a room has an accountable party, and this is one of the things they are accountable for. It has a cost, and the cost belongs on screen rather than in a comment.
Two things the words have to carry
Neither is visible from the verb:
adminmints epochs, and minting an epoch is how a member is removed. A party holding it can remove any other, including the owner's own agents, by declining to seal the new key to them.An authority credential conferring nothing is refused before it is sent, rather than being a neutral-looking default the owner discovers at the member's first refused operation.
The signing key is typed in, not derived
Nothing maps a room's DID to the key it was minted with, and inventing that mapping would add a lifecycle to get wrong — a binding that goes stale, or disagrees with the DID document after a rotation. A wrong key produces a credential that fails to verify against the room's document: loud, and at first use. The missing-field message says it is not derived, because that is the field an operator is likeliest to assume is optional.
Verification
npm run lint,npm run build,npm testall green — 1039 tests, 0 failures, 9 of them new (measured against a 392 baseline on main, not assumed). Built bundles checked: the sixspec/rooms/owner/occurrences are all inmanager.jsand nowhere else.Still outstanding
Registering a room with a host, and fetching a room's history — both need trustoverip/dtgwg-trust-tasks-tf#402, which is green and awaiting merge. Record browse/read/write needs the same.