Skip to content

Introduce tool:list verb for ingress and tool:read for egress filtering#4050

Open
ghaskins wants to merge 1 commit intostacklok:mainfrom
ghaskins:list-filtering
Open

Introduce tool:list verb for ingress and tool:read for egress filtering#4050
ghaskins wants to merge 1 commit intostacklok:mainfrom
ghaskins:list-filtering

Conversation

@ghaskins
Copy link
Contributor

@ghaskins ghaskins commented Mar 9, 2026

Summary

Previously, listing tools used the tool:call verb for both ingress authorization and egress response filtering, making it impossible to distinguish between a user discovering available tools versus invoking them with potential side effects.

Fixes #4048

Type of change

  • Bug fix
  • New feature
  • Refactoring (no behavior change)
  • Dependency update
  • Documentation
  • Other (describe): Enhancement to authz model

Test plan

  • Unit tests (task test)
  • E2E tests (task test-e2e)
  • Linting (task lint-fix)
  • Manual testing (describe below)

Changes

This change introduces:

  • A new ingress tool:list verb for tool listing requests, allowing policy authors to independently control access to tool discovery
  • Egress filtering switches from tool:call to tool:read for filtering listed tools in responses, reflecting that listing is a read-only discovery operation

The distinction between read-only discovery (tool:list/tool:read) and potentially mutable actions (tool:call) is now clear in both policies and audit logs.

Does this introduce a user-facing change?

Yes. This is a breaking change for users with existing Cedar policies that relied on tool:call to gate tool listing.

@github-actions github-actions bot added the size/XS Extra small PR: < 100 lines changed label Mar 9, 2026
@codecov
Copy link

codecov bot commented Mar 9, 2026

Codecov Report

❌ Patch coverage is 81.48148% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.67%. Comparing base (c474326) to head (c1bdae4).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
pkg/authz/middleware.go 70.00% 2 Missing and 1 partial ⚠️
pkg/authz/authorizers/cedar/core.go 87.50% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4050      +/-   ##
==========================================
- Coverage   68.68%   68.67%   -0.01%     
==========================================
  Files         454      458       +4     
  Lines       46027    46255     +228     
==========================================
+ Hits        31612    31766     +154     
- Misses      11977    12041      +64     
- Partials     2438     2448      +10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refines the authorization model by separating tool discovery from tool invocation, adding an explicit ingress permission for list requests and switching tool-list egress filtering to a read-style permission.

Changes:

  • Add an ingress authorization check for MCP list operations (MCPOperationList), enabling policies to gate discovery requests (e.g., Action::"list_tools").
  • Update tools list response filtering to authorize per-tool visibility via MCPOperationRead / Action::"read_tool" instead of call_tool.
  • Update unit/integration tests and Cedar authorizer logic to support read_tool and the new list-operation authorization requirement.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pkg/authz/middleware.go Adds ingress authorization for list operations before response filtering.
pkg/authz/response_filter.go Switches tool list filtering from call to read authorization.
pkg/authz/authorizers/cedar/core.go Adds Cedar support for authorizing read_tool operations.
pkg/authz/middleware_test.go Updates middleware tests to include new list permissions and tool visibility semantics.
pkg/authz/response_filter_test.go Updates response filtering tests to permit read_tool for tool visibility.
pkg/authz/integration_test.go Updates integration tests to permit list operations and use read_tool for tool visibility.
pkg/vmcp/auth/factory/authz_not_wired_test.go Adjusts policy setup to reflect new list permissions (vMCP wiring tests).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

r.Context(),
featureOp.Feature,
authorizers.MCPOperationList,
"metadata",
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For list operations, the middleware is passing a hard-coded resourceID ("metadata") into AuthorizeWithJWTClaims. This changes the resource/mcp.resource_id seen by non-Cedar authorizers (e.g., the HTTP PDP authorizer will emit mrn:mcp:<server>:tool:metadata for tools/list), which is likely unintended and makes list authorization harder to reason about. Prefer passing an empty resourceID (or the parsed cursor if you intentionally want pagination-aware decisions).

Suggested change
"metadata",
"",

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yrobla I left this one, as the assignment was intentional. The rationale was that this presents a verb of "tool:list" with a resource MRN of "mrn:...:tool:metadata", which makes sense to me, i.e. we are listing the tool's metadata (name, prompts, etc). Thoughts?

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@github-actions github-actions bot added size/XS Extra small PR: < 100 lines changed and removed size/XS Extra small PR: < 100 lines changed labels Mar 11, 2026
@github-actions github-actions bot added size/XS Extra small PR: < 100 lines changed and removed size/XS Extra small PR: < 100 lines changed labels Mar 11, 2026
@ghaskins ghaskins marked this pull request as ready for review March 11, 2026 21:53
Previously, listing tools used the tool:call verb for both ingress
authorization and egress response filtering, making it impossible to
distinguish between a user discovering available tools versus invoking
them with potential side effects.

This change introduces:
- A new ingress tool:list verb for tool listing requests, allowing
  policy authors to independently control access to tool discovery
- Egress filtering switches from tool:call to tool:read for filtering
  listed tools in responses, reflecting that listing is a read-only
  discovery operation

The distinction between read-only discovery (tool:list/tool:read) and
potentially mutable actions (tool:call) is now clear in both policies
and audit logs.

NOTE: This is a breaking change for users with existing Cedar policies
that relied on tool:call to gate tool listing.

Signed-off-by: Greg Haskins <greg@manetu.com>
@github-actions github-actions bot added size/XS Extra small PR: < 100 lines changed and removed size/XS Extra small PR: < 100 lines changed labels Mar 11, 2026
Copy link
Contributor

@jerm-dro jerm-dro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @ghaskins, I left a comment an issue, so I can get fully onboard with this change in whatever form it takes. I can take a closer look at this PR once as I understand the direction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XS Extra small PR: < 100 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Distinguish tool discovery from tool invocation in authorization and audit

3 participants