Add name attribute alias on Resource entities#4907
Merged
Conversation
The enterprise Cedar schema (platform-authz branch, 02-cedar-compilation.md
§ entity types) declares "name" as a required String attribute on all three
entity kinds — Tool, Prompt, and Resource. Tool and Prompt entities already
had "name" populated by CreateResourceEntity, but authorizeResourceRead
built its own attributes map with only "uri", so Resource entities lacked
the attribute and would fail schema validation when the enterprise
controller compiles policies.
Add "name": resourceURI alongside the existing "uri": resourceURI in
authorizeResourceRead so Resource entities satisfy the schema.
In CreateResourceEntity, default "name" to resourceID only when the
caller has not already provided one — authorizeResourceRead sets name
to the original unsanitized URI before passing the sanitized form as
resourceID, and the caller's value must survive.
Preserving the caller-provided name also exposes the original URI to
policies, so authors can match on the form they actually know (e.g.
resource.name == "file:///...") rather than the Cedar-sanitized entity
ID.
E2E tested in a Kind cluster with real Entra ID tokens:
permit(principal in THVGroup::"mcp-admin",
action == Action::"call_tool",
resource in MCP::"entra-role-test")
when { resource.name == "echo" };
Entra JWT: { "roles": ["mcp-admin", "developer"] }
call_tool "echo" -> 200 (resource.name matches)
call_tool "nonexistent_tool" -> 403 (name mismatch)
Fixes #4766
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4907 +/- ##
==========================================
- Coverage 69.26% 69.23% -0.04%
==========================================
Files 535 535
Lines 55354 55356 +2
==========================================
- Hits 38343 38325 -18
- Misses 14068 14087 +19
- Partials 2943 2944 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
JAORMX
approved these changes
Apr 17, 2026
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
authorizeResourceReadlacked anameattribute, while Tool and Prompt entities had one populated byCreateResourceEntity. This allows the admin to declarename: Stringas required on all three entity kinds"name": resourceURIto the attributes map inauthorizeResourceReadso Resource entities satisfy the schema.CreateResourceEntitydefaultnametoresourceIDonly when the caller has not already set it, so the unsanitized URI supplied byauthorizeResourceReadsurvives and policies can match on the real URI rather than the Cedar-sanitized entity ID.Fixes #4766
Type of change
Test plan
task test)Manual E2E in a Kind cluster with real Entra ID tokens, using this policy:
With an Entra JWT carrying
"roles": ["mcp-admin", "developer"]:call_tool "echo"→ 200 (resource.namematches)call_tool "nonexistent_tool"→ 403 (name mismatch)Two regression unit tests were added:
TestCreateResourceEntity_NamePreservation— guards against reintroducing the unconditionalattributes["name"] = resourceIDoverwrite.core_test.goexercising theauthorizeResourceReadpath to confirm thenameattribute is emitted.