A session cannot enumerate the sessions of the identity it is, and the surface may be MAS rather than Synapse #147

Open
opened 2026-09-02 00:47:03 +00:00 by jlxq0 · 0 comments
Owner

A server that authenticates as a user cannot enumerate that user's sessions. matrix-mcp exposes 62 tools and none lists or deletes a device: there is no devices tool, no logout, and nothing in src/mcp.rs calls the /devices endpoint. verify_status reads the caller's own device and nothing else.

So a request to prune stale devices for @julian:kampong.social could not be answered by any session holding any mount of this server, including the ones that authenticate as him. The task went back unstarted for want of a route rather than for want of authorisation.

The class, which is the part worth keeping

Third instance this week of something no session can ask about itself, and the other two are unrelated systems:

  • tmux display-message without -t answers about the calling pane's session, so a pane asking which window it is in gets a durable, wrong id.
  • A Home Assistant token's last_used_at never moves, so nothing distinguishes a live token from a dead one.
  • And this: a session cannot list the sessions of the identity it is.

A missing endpoint is a gap; three of these is a shape. Each is a real state with no instrument on the side that holds it, which is why each was found by somebody outside noticing rather than by the thing itself reporting.

The surface is probably MAS, not Synapse

The obvious route is Synapse's admin API:

GET    /_synapse/admin/v2/users/{user}/devices
DELETE /_synapse/admin/v2/users/{user}/devices/{deviceId}

But this deployment delegates authentication to MAS via the stable matrix_authentication_service integration rather than the experimental msc3861 block, which Synapse 1.157 removed. MAS owns every session and every token, so the Synapse view is at best partial, and a device pruned there may leave its OAuth session alive.

This is corroborated from inside this repository without reading any homeserver config: MATRIX_MCP_AUTHORIZATION_SERVER points at MAS, and src/mas.rs reads the device binding out of the MSC2967 urn:matrix:org.matrix.msc2967.client:device:<id> scope, which is MAS minting it.

And the MAS admin surface was confirmed on the running instance earlier, during the device-key work, as MAS 1.23:

GET  /api/admin/v1/oauth2-sessions
POST /api/admin/v1/oauth2-sessions/{id}/finish

That confirmation is Alan's rather than mine and I have not run either call. It is named here so the next person does not repeat the search, and because it makes the answer to "which surface owns a session" checkable rather than open.

What this issue is asking for

Not necessarily a tool. The decision is whether this server should be able to answer "which sessions exist for the identity I am" at all, given that:

  • it would be a read of the caller's own account rather than another user's, so it needs no admin credential;
  • the channel mount is deliberately small and this would not belong on it;
  • and if the answer lives in MAS rather than Synapse, the tool is a MAS call rather than a Matrix one, which is a different dependency than anything here has today.

A whoami that could say how many sessions this identity has, and when each was last seen, would have answered the original request without any admin access. That is the narrow version and it is consistent with the whoami-carries-the-allowlist proposal in #129.

  • #129, a bot that cannot read its own allowlist, and the argument for putting the answer on whoami.
  • #137, a mount that cannot tell whether it is still receiving.
  • #139, no session able to ask whether its own device is cross-signed.
A server that authenticates **as** a user cannot enumerate that user's sessions. `matrix-mcp` exposes 62 tools and none lists or deletes a device: there is no `devices` tool, no `logout`, and nothing in `src/mcp.rs` calls the `/devices` endpoint. `verify_status` reads the caller's **own** device and nothing else. **So a request to prune stale devices for `@julian:kampong.social` could not be answered by any session holding any mount of this server**, including the ones that authenticate as him. The task went back unstarted for want of a route rather than for want of authorisation. ## The class, which is the part worth keeping **Third instance this week of something no session can ask about itself**, and the other two are unrelated systems: - `tmux display-message` without `-t` answers about the calling pane's session, so a pane asking which window it is in gets a durable, wrong id. - A Home Assistant token's `last_used_at` never moves, so nothing distinguishes a live token from a dead one. - And this: a session cannot list the sessions of the identity it is. **A missing endpoint is a gap; three of these is a shape.** Each is a real state with no instrument on the side that holds it, which is why each was found by somebody outside noticing rather than by the thing itself reporting. ## The surface is probably MAS, not Synapse The obvious route is Synapse's admin API: GET /_synapse/admin/v2/users/{user}/devices DELETE /_synapse/admin/v2/users/{user}/devices/{deviceId} **But this deployment delegates authentication to MAS** via the stable `matrix_authentication_service` integration rather than the experimental `msc3861` block, which Synapse 1.157 removed. **MAS owns every session and every token**, so the Synapse view is at best partial, and a device pruned there may leave its OAuth session alive. This is corroborated from inside this repository without reading any homeserver config: `MATRIX_MCP_AUTHORIZATION_SERVER` points at MAS, and `src/mas.rs` reads the device binding out of the MSC2967 `urn:matrix:org.matrix.msc2967.client:device:<id>` scope, which is MAS minting it. **And the MAS admin surface was confirmed on the running instance earlier**, during the device-key work, as MAS 1.23: GET /api/admin/v1/oauth2-sessions POST /api/admin/v1/oauth2-sessions/{id}/finish That confirmation is Alan's rather than mine and I have not run either call. **It is named here so the next person does not repeat the search**, and because it makes the answer to "which surface owns a session" checkable rather than open. ## What this issue is asking for Not necessarily a tool. **The decision is whether this server should be able to answer "which sessions exist for the identity I am" at all**, given that: - it would be a read of the caller's own account rather than another user's, so it needs no admin credential; - the channel mount is deliberately small and this would not belong on it; - and if the answer lives in MAS rather than Synapse, the tool is a MAS call rather than a Matrix one, which is a different dependency than anything here has today. **A `whoami` that could say how many sessions this identity has, and when each was last seen, would have answered the original request without any admin access.** That is the narrow version and it is consistent with the `whoami`-carries-the-allowlist proposal in #129. ## Related - #129, a bot that cannot read its own allowlist, and the argument for putting the answer on `whoami`. - #137, a mount that cannot tell whether it is still receiving. - #139, no session able to ask whether its own device is cross-signed.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
jlxq0/matrix-mcp#147
No description provided.