Skip to content

feat(manager): issue in a room's name — invitation, membership, authority - #207

Merged
stormer78 merged 1 commit into
mainfrom
feat/rooms-owner-pane
Sep 8, 2026
Merged

feat(manager): issue in a room's name — invitation, membership, authority#207
stormer78 merged 1 commit into
mainfrom
feat/rooms-owner-pane

Conversation

@stormer78

Copy link
Copy Markdown
Contributor

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/create they are reachable from a browser. (See #206 for why that distinction exists.)

Three verbs, because the membership model has three ideas in it

What it is
Invitation 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, and on a private room with nobody outside able to tell them they are there. Single-use, consumed on entry.
Membership What a member presents afterwards. It 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 — exactly what the sealed tiers exist to prevent.
Authority What they may do. Membership admits a party; this says whether they may write, curate or admin. A room can admit someone who may only read.

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:

  • An invitation with no expiry is a standing right to enter, held by whoever ends up with the bytes. Single-use bounds how many people it admits — not how long it keeps admitting one.
  • admin mints 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 test all green — 1039 tests, 0 failures, 9 of them new (measured against a 392 baseline on main, not assumed). Built bundles checked: the six spec/rooms/owner/ occurrences are all in manager.js and 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.

…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>
@stormer78
stormer78 merged commit e8df516 into main Sep 8, 2026
3 checks passed
@stormer78
stormer78 deleted the feat/rooms-owner-pane branch September 8, 2026 17:48
@affinidi-appsecurity-bot

Copy link
Copy Markdown

🛡️ AI Agentic Security Code Review

🔎 A manual security review is recommended before merging. Please contact the Security team for specifics and remediation guidance.

ℹ️ Detailed findings are not published on public repositories; the Security team holds the complete report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants