Uh oh!
There was an error while loading. Please reload this page.
refactor(mcp): resolve tool access as three intersecting layers - #992
Conversation
Environment policy, team policy and the key's own block now carry the same allow/deny shape and combine by intersecting allow and unioning deny. A team policy narrows the environment layer instead of replacing it, and a key that configures nothing adds no constraint. Drops the mode machinery this replaces: McpPolicy.mode, McpAccess.mode and the key's allowed_tools field. A layer that grants nothing spells its allow side [], and one that only subtracts spells it ["*"]; allow is required on every layer so neither is reachable by omission. With no layer present at all the grant is empty, so MCP access stays granted explicitly.
Rewrites the access-policy e2e around the three-layer contract: a key with no block of its own, a team layer narrowing the environment, a wide-open key that still cannot widen, all three layers intersecting, an empty allow list blocking everything, and deletion of the last layer dropping to no access rather than to everything.
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in:44 minutes Limit details: You’ve used all 2 included reviews currently available. Your 55 included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour. Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits within each organization. For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (24)
Comment |
MCP tool access was resolved through two different mechanisms glued together by a
modefield: anmcp_access.modeofinherit/restrict/denyon the key, plus alegacystate (no block at all) where the key'sallowed_toolswas its whole grant and the policies could not reach it. A team policy replaced the environment grant rather than narrowing it, andallowed_toolsandmcp_access.allowwere two fields expressing the same thing, withmodedeciding which one counted. The result was four key states, three policy modes, and a per-environment "migrate legacy keys" batch operation in the control plane to move keys between them.This collapses all of it into one rule. Three layers of identical shape contribute to the ACL — the environment policy, the key's team policy, and the key's own
mcp_accessblock — each carryingallowanddenypattern lists. Allow sides intersect, deny sides union, and a layer that is absent (no row, disabled, or no block on the key) imposes no constraint. With no layer present at all the grant is empty, so MCP access is still granted explicitly and never by the absence of configuration.What that removes:
McpPolicy.mode(none/selected/all) —allisallow: ["*"],noneisallow: []McpAccess.mode(inherit/restrict/deny) — inheriting is what a key does when it has no block, narrowing is what itsallowlist does, and denying everything isallow: []ApiKey.allowed_tools— the key's layer ismcp_access.allowallowis now required on every layer, so a layer that only means to subtract tools has to spell its allow side["*"]instead of silently granting nothing. A policy or key block carrying onlydenyis a schema error, not a lockout.Behaviour changes beyond the field shapes: a team policy now narrows the environment layer instead of replacing it, so it can no longer grant a tool the environment does not; and a key with no
mcp_accessblock now follows the policy layers instead of standing outside them.The control-plane half (schema, projection, dashboard, and the removal of the legacy-key migration flow) follows in a paired PR.