Skip to content

Guard Cedar policy attribute access with has operator#41

Merged
jhrozek merged 1 commit intomainfrom
fix/cedar-has-guards-safe-tools
Mar 16, 2026
Merged

Guard Cedar policy attribute access with has operator#41
jhrozek merged 1 commit intomainfrom
fix/cedar-has-guards-safe-tools

Conversation

@JAORMX
Copy link
Contributor

@JAORMX JAORMX commented Mar 16, 2026

Summary

  • Fix safe-tools Cedar policies to use resource has <attr> && guards before accessing tool annotation attributes
  • Without guards, MCP servers that set partial annotations (e.g. GitHub sets readOnlyHint but not destructiveHint) had all their tools incorrectly denied — Cedar treats missing attribute access as an evaluation error, and toolhive's pre-flight check treats any error as a hard deny
  • Rewrite profiles_test.go to exercise the actual Cedar engine against 6 annotation scenarios × 2 profiles × 2 actions (24 cases), replacing substring-matching tests that wouldn't have caught this bug

Before: safe-tools allowed only 7 tools (osv + oci-registry — the only servers with complete annotations)
After: safe-tools allows 59 tools (all read-only tools from GitHub, context7, osv, oci-registry)

Test plan

  • task verify passes (fmt, lint, test)
  • TestCedarAuthorizationDecisions covers the exact partial-annotation scenario that was broken (scenario 3: only readOnlyHint=true, no other hints)
  • Verified end-to-end with a debug harness against live MCP servers (osv, oci-registry, github, context7, fetch, slack)

🤖 Generated with Claude Code

The safe-tools Cedar policies accessed tool annotation attributes
(readOnlyHint, destructiveHint, openWorldHint) directly in `when`
clauses. When an MCP server omits an annotation, Cedar treats the
missing attribute access as an evaluation error. Toolhive's pre-flight
authz check then hard-denies the tool, even if another policy would
have permitted it.

This broke safe-tools for servers that set partial annotations (GitHub
MCP server sets readOnlyHint but not destructiveHint; context7 sets
only readOnlyHint). All their read-only tools were incorrectly denied.

Fix by prepending `resource has <attr> &&` before each attribute
access. Missing attributes now evaluate to false (policy not
satisfied) instead of error, letting other policies permit the tool.

Also rewrites profiles_test.go to exercise the actual Cedar engine
against 6 realistic annotation scenarios x 2 profiles x 2 actions,
replacing the previous substring-matching tests that wouldn't have
caught this bug.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jhrozek jhrozek merged commit 42a96bb into main Mar 16, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants