Download the PHP package rasuvaeff/yii3-mcp-rbac-bridge without Composer
On this page you can find all versions of the php package rasuvaeff/yii3-mcp-rbac-bridge. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download rasuvaeff/yii3-mcp-rbac-bridge
More information about rasuvaeff/yii3-mcp-rbac-bridge
Files in rasuvaeff/yii3-mcp-rbac-bridge
Package yii3-mcp-rbac-bridge
Short Description Per-user RBAC for MCP servers: yiisoft/rbac permissions on yii3-mcp tool calls, visibility filtering and session-identity binding
License BSD-3-Clause
Homepage https://github.com/rasuvaeff/yii3-mcp-rbac-bridge
Informations about the package yii3-mcp-rbac-bridge
rasuvaeff/yii3-mcp-rbac-bridge
Per-user authorization for rasuvaeff/yii3-mcp
servers over the Yii3 auth stack — the application-facing alternative to
OAuth 2.1: RBAC permissions enforced on every tools/call, permission-aware
tools/list filtering, and session-identity binding against session
hijacking.
Using an AI coding assistant? llms.txt contains a compact API reference you can share with the model. Contributors: see AGENTS.md.
Requirements
| Requirement | Version |
|---|---|
| PHP | 8.3 – 8.5 |
rasuvaeff/yii3-mcp |
^1.1 \|\| ^2.0 |
yiisoft/access |
^2.0 (bind AccessCheckerInterface to your RBAC manager) |
yiisoft/user |
^2.0 (identity of the current request) |
Installation
The model: two auth layers
SharedSecretMiddleware (yii3-mcp) stays — it is machine auth: may this
MCP client talk to this endpoint at all. This bridge adds user auth: what
may the authenticated user behind the call actually do. Both layers run;
removing the shared secret does not follow from adding RBAC.
Usage
1. Declare permissions on tools
Restriction is explicit and per-tool: tools without a permission stay open
(behind the shared secret). #[RequiredPermission] on a method without
#[McpTool] fails the build — a permission that would never be enforced is
a bug, not a default. One tool name mapped to two different permissions by
attributes fails the build too (a silent last-one-wins would enforce an
arbitrary one); explicit overrides win by design.
Tool names: what the map keys must be
PermissionMap keys are tool names, and the bridge derives each one exactly as
yii3-mcp registers it — so list and call can never key off different names:
| Tool declaration | Registered name = map key |
|---|---|
#[McpTool(name: 'order.status')] |
order.status — the explicit name wins |
#[McpTool] on public function status() |
status — the method name |
#[McpTool] on public function __invoke() |
the class short name (e.g. RefundTool), not __invoke |
fromToolClasses() computes these keys for you. Only an explicit map (the
$overrides argument, or new PermissionMap([...])) is yours to key correctly —
for an invokable tool that key is the class short name:
A key that matches no registered tool is inert (the tool stays unrestricted), so keep explicit keys in sync with the tool names above.
2. Wire the bridge
Split identity wiring by entry point; stdio has no HTTP CurrentUser:
AccessCheckerInterface comes from your RBAC setup (yiisoft/rbac manager
with rbac-php/rbac-db storage — see suggest).
What each piece does
| Class | Role |
|---|---|
RbacToolCallInterceptor |
rejects tools/call without the mapped permission (regular MCP tool error, fail-closed for guests) |
RbacToolVisibility |
hides the same tools from tools/list — list and call can never disagree (one PermissionMap) |
SessionIdentityInterceptor |
binds the MCP session to its first identity; a leaked Mcp-Session-Id presented with another user's token is rejected |
PermissionMap |
tool name → permission: #[RequiredPermission] scan + explicit overrides |
CurrentUserIdentitySource |
identity id from yiisoft/user CurrentUser (null = guest); implement IdentitySourceInterface for stdio/custom setups |
StaticIdentitySource |
fixed config/env identity for console/stdio; null means guest |
Security notes
- Two session bindings, two layers. yii3-mcp 2.0 binds every session to
the MCP client that created it (immutable owner stamped at
initialize); this bridge'sSessionIdentityInterceptorbinds the session to the application user on the firsttools/call(the yii3-mcp interceptor chain does not seeinitialize). The layers complement each other: betweeninitializeand the first call the session still carries no user identity — nothing is authorized in that window, so nothing is exposed — but on core 2.0 a foreign MCP client can no longer slip into that window with a leakedMcp-Session-Id; only a race inside the same client remains. On core 1.x the client-owner layer does not exist and the first-call user binding is the only session protection. - Session-ownership rejections bypass this bridge. yii3-mcp 2.0 rejects a
foreign or ownerless session (the SDK-shaped 404 from
McpAction,SessionOwnershipExceptionfromInterceptingReferenceHandler) BEFORE the interceptor chain runs — such a rejection never reaches this bridge's RBAC interceptor or visibility filter. Hijack attempts stopped by the core are therefore visible only in the application/web-server logs, not in anything this bridge observes. - Guests are first-class: a guest binds the session as a guest and is denied
on every permission-mapped tool (
AccessCheckerInterfacereceivesnull). The internal guest marker cannot be forged by a literal"guest"user id. - Permission revocation applies on the next call (fail-closed). Live
notifications/tools/list_changedon revocation is not part of this version — the SDK exposes it only with an event dispatcher, which yii3-mcp's factory does not yet carry. - For stdio (
mcp:serve) there is no HTTP request: bindIdentitySourceInterfacetoStaticIdentitySource, or leave the shared secret as the only (machine) identity. - Guest plus
RbacToolVisibilitycan legally produce an emptytools/list. This is an authorization result, not a coremcp:listfailure; verify the console identity binding before treating zero visible tools as a registry bug.
Examples
See examples/ — runs offline.
| Script | Shows | Needs server? |
|---|---|---|
rbac.php |
Filtered listing, allowed/denied calls, session binding | no |
Dependency analysers
This leaf package is selected by the root application through config-plugin and may legitimately have no class reference in an autoloaded source directory. Keep the direct dependency: the application, not a core package, selects the backend or bridge. Scope the Composer Dependency Analyser exception to this package:
composer-require-checker detects used but undeclared symbols, not unused
packages, so this config-only dependency needs no require-checker suppression.
Development
No PHP/Composer on the host — run in Docker via the composer:2 image:
Or with Make: make build, make cs-fix, make psalm, make test.
License
BSD-3-Clause. See LICENSE.md.
All versions of yii3-mcp-rbac-bridge with dependencies
mcp/sdk Version ~0.6.0 || ~0.7.0
rasuvaeff/yii3-mcp Version ^1.1 || ^2.0
yiisoft/access Version ^2.0
yiisoft/user Version ^2.0