You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Make the right to request a capability a capability of its own #324
Make the right to request a capability a capability of its own
room.join and the generic capability.request are deliberately ungated: createCapabilityRequestHandler runs no token check, and access control is the receiver's decision (in the console, a human approving). So anyone who can reach a device can put an approval prompt in front of its user. There is no way for a receiver to say who may ask for a given capability, or to pre-authorise a class of requesters without a human in the loop.
Design direction: under the same owner-rooted model as #323, the right to request a capability is a permission the resource's owner holds, can grant, and can pass on, presented with the request. Like every other permission it is conditional, with trilean conditions (or similar) constraining what its holder may do, including barring passing the request permission on to itself.
Constraints:
Contact from a stranger with no prior relationship must stay possible where the receiver wants it (a first DM is a request with no token behind it), so the gate is optional per verb and scope: open by default for DM-style contact, required where the receiver sets a policy.
A requester can only hold a request token if someone granted it one, so this protects only what is reachable through an earlier relationship. The spec must state that plainly rather than imply it closes the stranger case.
Where the request token travels: the existing token field of the manage-request, or a separate field. The capability.request params are an open tail, so this may need no schema change.
How the receiver's policy is expressed and stored, and what the console shows when a request is refused by policy rather than by a person.
Registry entry, verifier, and golden vectors in conformance/ for both implementations.
Related: #323 (the grant-permission model this follows), #237.
Closing without implementing. A request already carries an optional token field, and what a receiver does with it is the receiver's policy. To pre-authorise a class of requesters, accept a request presenting a token it already honours (a group:member token for its own group, say); to stop prompt flooding, apply rate limits and block lists to the rest. That uses identity and tokens as they are, so a dedicated request capability would be a wrapper around them and fails the orthogonality test. It would not close the stranger case either, since a first contact holds no token and a receiver that wants to hear from strangers has to be reachable without one. The reasoning is recorded in spec/management.cddl, #325. What remains is console-side policy (auto-accept for known groups, rate limits on prompts), which is application work that needs a concrete product requirement before it gets its own issue.
Activity
Mearman commentedon Oct 1, 2026
Closing without implementing. A request already carries an optional
tokenfield, and what a receiver does with it is the receiver's policy. To pre-authorise a class of requesters, accept a request presenting a token it already honours (agroup:membertoken for its own group, say); to stop prompt flooding, apply rate limits and block lists to the rest. That uses identity and tokens as they are, so a dedicated request capability would be a wrapper around them and fails the orthogonality test. It would not close the stranger case either, since a first contact holds no token and a receiver that wants to hear from strangers has to be reachable without one. The reasoning is recorded in spec/management.cddl, #325. What remains is console-side policy (auto-accept for known groups, rate limits on prompts), which is application work that needs a concrete product requirement before it gets its own issue.github-actions commentedon Oct 1, 2026
🎉 This issue has been resolved in version 3.8.0 🎉
The release is available on:
Your semantic-release bot 📦🚀