Part of stacklok/stacklok-enterprise-platform#stacklok/stacklok-enterprise-platform#376
Description
Add a "name" attribute to Resource entities in authorizeResourceRead alongside the existing "uri" attribute, both set to the resource URI value. The enterprise Cedar schema declares "name" as the canonical attribute on all three resource types (Tool, Prompt, Resource) for consistency, but authorizeResourceRead currently only sets "uri". Without "name", enterprise-generated Cedar policies that reference resource.name on Resource entities will silently fail schema validation.
Context
The platform authorization Cedar schema (defined in the design document 02-cedar-compilation.md) uses "name" as the primary attribute for Tool, Prompt, and Resource entity types. Tool and Prompt entities already set "name" in authorizeToolCall and authorizePromptGet respectively. However, authorizeResourceRead only sets "uri" -- an OSS-specific attribute that predates the enterprise schema. Adding "name" aligns Resource entities with the other two resource types and ensures enterprise-compiled policies work correctly.
Note: CreateResourceEntity in entity.go (line 73) does set attributes["name"] = resourceID as a default, but authorizeResourceRead passes its own attributes map via mergeContexts which includes "uri" but not "name". Since the explicit attributes override the defaults during merge, the "name" from the entity factory is effectively overwritten by the attributes map that lacks it. Adding "name" explicitly in the authorizeResourceRead attributes map ensures it survives the merge.
Dependencies: None (this is an independent change)
Blocks: #4768 (group extraction integration may rely on consistent entity attributes)
Acceptance Criteria
Technical Approach
Recommended Implementation
In authorizeResourceRead (around line 481 of core.go), add "name": resourceURI to the attributes map. The change is a single line addition:
Current code:
attributes := mergeContexts(map[string]interface{}{
"uri": resourceURI,
"operation": "read",
"feature": "resource",
}, attrsMap)
Target code:
attributes := mergeContexts(map[string]interface{}{
"name": resourceURI, // canonical name used by Cedar schema
"uri": resourceURI, // backward-compatible alias
"operation": "read",
"feature": "resource",
}, attrsMap)
This is consistent with how authorizeToolCall and authorizePromptGet already set "name" on their respective resource entities.
Patterns & Frameworks
- Follow the existing
mergeContexts pattern used by authorizeToolCall (line 407) and authorizePromptGet (line 443), both of which already include "name" in their attributes map
- Cedar entity attribute conventions from the
cedar-policy/cedar-go library -- attributes are string-keyed maps that flow through convertMapToCedarRecord
- The
"name" attribute is already declared in the Cedar schema for Resource entities (type String, required), so this change makes the OSS authorizer schema-compliant
Code Pointers
pkg/authz/authorizers/cedar/core.go -- authorizeResourceRead method (line ~464): the one function that needs modification. Add "name": resourceURI to the attributes map literal
pkg/authz/authorizers/cedar/core.go -- authorizeToolCall (line ~392): reference for how "name" is already set on Tool entities
pkg/authz/authorizers/cedar/core.go -- authorizePromptGet (line ~428): reference for how "name" is already set on Prompt entities
pkg/authz/authorizers/cedar/entity.go -- CreateResourceEntity (line 63): note that line 73 sets attributes["name"] = resourceID as a default, but this is overridden when authorizeResourceRead passes an attributes map without "name" through mergeContexts
pkg/authz/authorizers/cedar/core_test.go -- existing test patterns for AuthorizeWithJWTClaims with MCPFeatureResource / MCPOperationRead (line ~204)
Component Interfaces
No interface changes required. The change is purely internal -- adding one key to an attributes map literal within authorizeResourceRead. The function signature, return type, and behavior for existing callers remain identical.
// No signature change -- only the internal attributes map is modified:
func (a *Authorizer) authorizeResourceRead(
clientID, resourceURI string,
claimsMap map[string]interface{},
attrsMap map[string]interface{},
) (bool, error) {
// ... unchanged except for the attributes map literal ...
}
Testing Strategy
Unit Tests
Integration Tests
Edge Cases
Out of Scope
- Removing the
"uri" attribute (it must be kept for backward compatibility with existing standalone Cedar policies)
- Changes to
entity.go -- the CreateResourceEntity default name attribute is fine as-is; the fix is in the caller
- Changes to other
authorize* methods (authorizeToolCall, authorizePromptGet, authorizeFeatureList) -- they already handle name correctly or are not relevant
- Cedar schema validation enforcement in the OSS authorizer (the schema is only used by the enterprise controller)
References
- Design doc:
04-oss-changes.md -- Section 8 ("Rename uri attribute to name on Resource entities") describes this change with before/after code
- Cedar schema:
02-cedar-compilation.md -- Section 7 ("Cedar Schema") defines Resource entity with a required name attribute of type String
- Compatibility table:
04-oss-changes.md -- confirms resource.uri remains as alias ("Yes -- alias")
Part of stacklok/stacklok-enterprise-platform#stacklok/stacklok-enterprise-platform#376
Description
Add a
"name"attribute to Resource entities inauthorizeResourceReadalongside the existing"uri"attribute, both set to the resource URI value. The enterprise Cedar schema declares"name"as the canonical attribute on all three resource types (Tool,Prompt,Resource) for consistency, butauthorizeResourceReadcurrently only sets"uri". Without"name", enterprise-generated Cedar policies that referenceresource.nameonResourceentities will silently fail schema validation.Context
The platform authorization Cedar schema (defined in the design document
02-cedar-compilation.md) uses"name"as the primary attribute forTool,Prompt, andResourceentity types.ToolandPromptentities already set"name"inauthorizeToolCallandauthorizePromptGetrespectively. However,authorizeResourceReadonly sets"uri"-- an OSS-specific attribute that predates the enterprise schema. Adding"name"alignsResourceentities with the other two resource types and ensures enterprise-compiled policies work correctly.Note:
CreateResourceEntityinentity.go(line 73) does setattributes["name"] = resourceIDas a default, butauthorizeResourceReadpasses its own attributes map viamergeContextswhich includes"uri"but not"name". Since the explicit attributes override the defaults during merge, the"name"from the entity factory is effectively overwritten by the attributes map that lacks it. Adding"name"explicitly in theauthorizeResourceReadattributes map ensures it survives the merge.Dependencies: None (this is an independent change)
Blocks: #4768 (group extraction integration may rely on consistent entity attributes)
Acceptance Criteria
authorizeResourceReadsets"name": resourceURIin the attributes map passed toCreateEntitiesForRequestauthorizeResourceReadretains"uri": resourceURIfor backward compatibility with existing standalone Cedar policies"name"and"uri"attributes carry the same value (the resource URI)authorizeResourceReadexposes bothnameanduriattributes with the same valueTechnical Approach
Recommended Implementation
In
authorizeResourceRead(around line 481 ofcore.go), add"name": resourceURIto the attributes map. The change is a single line addition:Current code:
Target code:
This is consistent with how
authorizeToolCallandauthorizePromptGetalready set"name"on their respective resource entities.Patterns & Frameworks
mergeContextspattern used byauthorizeToolCall(line 407) andauthorizePromptGet(line 443), both of which already include"name"in their attributes mapcedar-policy/cedar-golibrary -- attributes are string-keyed maps that flow throughconvertMapToCedarRecord"name"attribute is already declared in the Cedar schema forResourceentities (typeString, required), so this change makes the OSS authorizer schema-compliantCode Pointers
pkg/authz/authorizers/cedar/core.go--authorizeResourceReadmethod (line ~464): the one function that needs modification. Add"name": resourceURIto the attributes map literalpkg/authz/authorizers/cedar/core.go--authorizeToolCall(line ~392): reference for how"name"is already set onToolentitiespkg/authz/authorizers/cedar/core.go--authorizePromptGet(line ~428): reference for how"name"is already set onPromptentitiespkg/authz/authorizers/cedar/entity.go--CreateResourceEntity(line 63): note that line 73 setsattributes["name"] = resourceIDas a default, but this is overridden whenauthorizeResourceReadpasses an attributes map without"name"throughmergeContextspkg/authz/authorizers/cedar/core_test.go-- existing test patterns forAuthorizeWithJWTClaimswithMCPFeatureResource/MCPOperationRead(line ~204)Component Interfaces
No interface changes required. The change is purely internal -- adding one key to an attributes map literal within
authorizeResourceRead. The function signature, return type, and behavior for existing callers remain identical.Testing Strategy
Unit Tests
resource.nameon aResourceentity evaluates correctly (PERMIT when name matches)resource.urion aResourceentity still evaluates correctly (backward compat -- PERMIT when uri matches)nameanduricarry the same value (the resource URI) by writing a policy that checksresource.name == resource.uriIntegration Tests
TestAuthorizeWithJWTClaimstest case "User with specific role in array can access resource" (line ~204) continues to pass -- this validates no regression in resource read authorizationEdge Cases
sanitizeURIForCedarfunction handles this for the entity ID, but the raw URI is stored in bothnameanduriattributes -- verify this is consistent withToolandPromptbehavior)Out of Scope
"uri"attribute (it must be kept for backward compatibility with existing standalone Cedar policies)entity.go-- theCreateResourceEntitydefaultnameattribute is fine as-is; the fix is in the callerauthorize*methods (authorizeToolCall,authorizePromptGet,authorizeFeatureList) -- they already handlenamecorrectly or are not relevantReferences
04-oss-changes.md-- Section 8 ("Renameuriattribute tonameon Resource entities") describes this change with before/after code02-cedar-compilation.md-- Section 7 ("Cedar Schema") definesResourceentity with a requirednameattribute of typeString04-oss-changes.md-- confirmsresource.uriremains as alias ("Yes -- alias")