Log when authorization policies filter list responses#4690
Merged
Conversation
When Cedar policies deny access to tools, prompts, or resources during list filtering, items are silently removed from the response. This makes it difficult to diagnose authorization issues since the MCP client shows empty capabilities with no explanation. Add DEBUG-level logs for each denied item and an INFO-level summary after filtering completes so operators can see that items were filtered and enable DEBUG to see which ones. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a generic AtMost utility (pkg/syncutil) that executes a function at most once per configurable interval, safe for concurrent use. Use it in the Cedar authorizer to emit a rate-limited DEBUG log of resolved JWT claim keys, helping operators see what claims are available for writing Cedar policies without enabling verbose per-request logging. Downgrade the authorization filtering summary logs from INFO to DEBUG to follow the "silent success" convention — a policy correctly denying access is working as intended, not something that warrants INFO output. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4690 +/- ##
==========================================
- Coverage 68.78% 68.68% -0.11%
==========================================
Files 506 508 +2
Lines 52599 52878 +279
==========================================
+ Hits 36180 36318 +138
- Misses 13617 13741 +124
- Partials 2802 2819 +17 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When Cedar policies deny tools, prompts, or resources during list filtering, items are silently removed from the response with zero log output. This makes it difficult for operators to diagnose authorization issues — the MCP client shows empty capabilities ("Capabilities: None") with no explanation of why. A community user hit this after upgrading to v0.15.0 when PR #4448 switched Cedar to evaluate upstream IDP access token claims, which had different claim keys than expected.
AtMostutility (pkg/syncutil) that executes a function at most once per configurable interval, safe for concurrent useTOOLHIVE_DEBUG=trueinproxyConfig.envType of change
Test plan
task test)task lint-fix)Changes
pkg/syncutil/atmost.gopkg/syncutil/atmost_test.gopkg/authz/authorizers/cedar/core.goresolveClaims()pkg/authz/tool_filter.gopkg/authz/response_filter.goDoes this introduce a user-facing change?
When
TOOLHIVE_DEBUG=trueis set inproxyConfig.env, operators will see:Special notes for reviewers
The
AtMostutility is intentionally generic (not logging-specific) so it can be reused for any rate-limited side-effect. It usesatomic.Int64CAS for lock-free concurrent safety, and accepts an injectablefunc() time.Timefor deterministic testing withouttime.Sleep.Generated with Claude Code