Skip to content

SEP-XXXX: Per-Notification Access Checks for Subscription Streams - #69

Open
RamjotSingh wants to merge 4 commits into
modelcontextprotocol:mainfrom
RamjotSingh:sep/per-notification-access-checks
Open

RamjotSingh wants to merge 4 commits into
modelcontextprotocol:mainfrom
RamjotSingh:sep/per-notification-access-checks

Conversation

@RamjotSingh

@RamjotSingh RamjotSingh commented Oct 30, 2026 •

Copy link
Copy Markdown

The original issue is described in #62

This is a split from #63 and builds on #67

Applies the server's resource-level access checks, such as ACLs and membership, to every notification on a subscriptions/listen stream, not only to the request that opened it. Notifications the principal could not obtain with a request are dropped. A stream that loses access to some of its entries keeps the rest; one that loses access to all of them ends with revoked.

Motivation and Context

A server checks two things before it serves a request: that the token is valid, and that the principal may access what the request asks for (#62). The proposal this builds on covers the token; this one covers the resource. Today, a stream opened before a user lost access to a resource keeps delivering its change notifications, revealing when a resource they can no longer read changes, and notifications about sub-resources, such as a private channel in a watched team, raise the same problem without any change in access.

How Has This Been Tested?

Prototype on a TypeScript SDK fork, branch poc/authorization-lifetime (reviewer guide), which implements the combined draft in #63. Every notification passes through a pluggable access check, authorize(authInfo, target).

  • Demo (pnpm --filter @mcp-examples/authorization-lifetime start:fast), scenario 3, step 3: access to an HR case is revoked during a change to it. One stream keeps receiving changes to config.json while notifications about the HR case stop; another, whose only entry is the HR case, stays open past the change rather than revealing when it happened.
  • Tests: a denied entry stops while the stream stays open; an access-change signal ends a stream left with no entries with revoked; a last entry lost during a change ends the stream only at its deadline.
  • Build, lint, typecheck, and the SDK test suites pass, apart from three Windows-only failures that also occur on unmodified upstream main.

Breaking Changes

None for clients, and no wire change. Servers that deliver these notifications today must stop, but the notifications dropped are ones the principal could not obtain with a request, and a client cannot tell a dropped notification from no change. A stream ends only when nothing it watches is still readable, which older clients see as a close without a response, the same as any other unexpected disconnect.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

AI disclosure: Ideas and specs are mine but I have used AI to link it back into the existing protocol and SEPs that introduced them as well as formulate into official language from my draft. POC has been built by AI as well on my guidance.

RamjotSingh and others added 2 commits October 30, 2026 02:47
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 642313f5-3121-4469-9a2d-58c03da64a23
The draft referred to Ending Subscription Streams When Authorization Ends
by a relative path that only resolved in the drafts folder. Point those
references at the proposal on its branch.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 642313f5-3121-4469-9a2d-58c03da64a23
RamjotSingh and others added 2 commits October 30, 2026 03:22
Ending Subscription Streams When Authorization Ends is now open as modelcontextprotocol#67.
Point references to the proposal as a whole at the pull request, and name
it in the header. References to its sections still point at the document on
the pull request's branch, since a pull request link cannot carry a section
anchor.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 642313f5-3121-4469-9a2d-58c03da64a23
modelcontextprotocol#67 is now titled Ending Subscription Streams with an Authorization Reason,
and its sections were reorganized. Use the new title, and point references
to its sections at their new places.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 642313f5-3121-4469-9a2d-58c03da64a23
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.

1 participant