Skip to content

Add tool annotation context for Cedar/HTTP authz#4102

Merged
JAORMX merged 3 commits intomainfrom
pr1-annotation-context-authorizer
Mar 11, 2026
Merged

Add tool annotation context for Cedar/HTTP authz#4102
JAORMX merged 3 commits intomainfrom
pr1-annotation-context-authorizer

Conversation

@JAORMX
Copy link
Copy Markdown
Collaborator

@JAORMX JAORMX commented Mar 11, 2026

Summary

  • Cedar policies can reference entity attributes like resource.readOnlyHint == true, but MCP tool annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) never reached the Cedar or HTTP PDP authorizers. This adds context-based annotation injection so authorization policies can make decisions based on tool properties.
  • Adds a ToolAnnotations struct and context helpers (WithToolAnnotations/ToolAnnotationsFromContext) in the authorizers package — the shared interface package that both Cedar and HTTP PDP already import, avoiding import cycles.
  • Cedar authorizer merges annotations into resource entity attributes, enabling policies like resource.readOnlyHint == true.
  • HTTP PDP authorizer includes annotations under context.mcp.annotations in the PORC structure.
  • This is the foundation for PR 2 (annotation cache for regular ToolHive) and PR 3 (vmcp annotation flow).

Type of change

  • New feature

Test plan

  • Unit tests (task test)
  • Linting (task lint-fix)

Changes

File Change
pkg/authz/authorizers/annotations.go New: ToolAnnotations struct, context helpers, AnnotationsToMap converter
pkg/authz/authorizers/annotations_test.go New: Round-trip context tests, nil handling, map conversion tests
pkg/authz/authorizers/cedar/core.go Modified: authorizeToolCall accepts context, reads annotations and merges into resource entity attributes; moved AuthorizeWithJWTClaims to public methods section
pkg/authz/authorizers/http/core.go Modified: AuthorizeWithJWTClaims enriches PORC context with annotations; new enrichPORCWithAnnotations helper
pkg/authz/authorizers/cedar/annotations_integration_test.go New: Integration tests verifying Cedar policies can use resource.readOnlyHint, resource.destructiveHint, and graceful degradation without annotations

Does this introduce a user-facing change?

No — this adds the internal plumbing. Users will benefit once annotations are populated (via annotation cache in PR 2 or vmcp discovery in PR 3), enabling Cedar policies that reference tool annotations.

Special notes for reviewers

  • Import cycle avoidance: Annotations live in pkg/authz/authorizers/ (not pkg/authz/) because Cedar and HTTP PDP packages import authorizers but not the parent authz package.
  • Annotations as resource attributes (not context): In Cedar, annotations become resource entity attributes (resource.readOnlyHint) rather than context values. This is more natural since annotations are intrinsic tool properties, not request-specific data.
  • Graceful degradation: When no annotations are in context, AnnotationsToMap returns nil, and mergeContexts skips nil maps — so existing behavior is completely unchanged.
  • Cedar multi-policy test: The forbid test case uses separate policy strings (one permit, one forbid) because UnmarshalCedar parses one policy per call.

Generated with Claude Code

@github-actions github-actions bot added the size/M Medium PR: 300-599 lines changed label Mar 11, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 11, 2026

Codecov Report

❌ Patch coverage is 95.12195% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.69%. Comparing base (144a4da) to head (f05b218).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
pkg/authz/authorizers/http/core.go 89.47% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4102      +/-   ##
==========================================
+ Coverage   68.68%   68.69%   +0.01%     
==========================================
  Files         453      454       +1     
  Lines       46011    46049      +38     
==========================================
+ Hits        31604    31635      +31     
- Misses      11967    11974       +7     
  Partials     2440     2440              

☔ 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.

@JAORMX JAORMX force-pushed the pr1-annotation-context-authorizer branch from 923d27a to cdd5c10 Compare March 11, 2026 14:26
@github-actions github-actions bot added size/M Medium PR: 300-599 lines changed size/L Large PR: 600-999 lines changed and removed size/M Medium PR: 300-599 lines changed size/L Large PR: 600-999 lines changed labels Mar 11, 2026
JAORMX and others added 3 commits March 11, 2026 16:42
Cedar policies can reference entity attributes like
`resource.readOnlyHint == true`, but tool annotations were never
reaching the authorizers. This adds context-based annotation injection
so both Cedar and HTTP PDP authorizers can use MCP tool annotations
(readOnlyHint, destructiveHint, idempotentHint, openWorldHint) in
authorization decisions.

- Add ToolAnnotations struct and context helpers in authorizers package
- Cedar authorizer merges annotations into resource entity attributes
- HTTP PDP authorizer includes annotations in PORC context
- Foundation for annotation cache (PR 2) and vmcp flow (PR 3)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reverse the Cedar mergeContexts order so standard resource attributes
(name, operation, feature) are applied last and cannot be overwritten by
annotation keys. Guard HTTP PDP annotation enrichment to tool-call
operations only. Add slog.Warn when enrichPORCWithAnnotations encounters
unexpected types instead of silently discarding context. Document the
trust boundary (annotations must come from the server-side registry) and
the asymmetric exposure paths between Cedar and HTTP authorizers.

Add unit tests for enrichPORCWithAnnotations (8 cases) and Cedar
attribute collision safety (5 cases).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Restore the original method ordering so the PR diff only shows the
actual logic changes, not a spurious move.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@JAORMX JAORMX force-pushed the pr1-annotation-context-authorizer branch from dce379d to f05b218 Compare March 11, 2026 14:42
@github-actions github-actions bot added size/L Large PR: 600-999 lines changed and removed size/L Large PR: 600-999 lines changed labels Mar 11, 2026
@JAORMX JAORMX merged commit 7f1d943 into main Mar 11, 2026
74 of 76 checks passed
@JAORMX JAORMX deleted the pr1-annotation-context-authorizer branch March 11, 2026 17:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/L Large PR: 600-999 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants