Skip to content

Add authorization policy reference and enhance Cedar docs#664

Open
JAORMX wants to merge 1 commit intomainfrom
add-authz-policy-reference
Open

Add authorization policy reference and enhance Cedar docs#664
JAORMX wants to merge 1 commit intomainfrom
add-authz-policy-reference

Conversation

@JAORMX
Copy link
Copy Markdown
Contributor

@JAORMX JAORMX commented Apr 3, 2026

Summary

Policy authors lacked a complete dictionary of Cedar entity types, actions, attributes, and annotations available when writing ToolHive authorization policies. The existing Cedar policies concept page also had no coverage of tool annotations, group membership, or real-world policy profiles.

This PR adds a dedicated reference page and enhances the concept page to close these gaps.

Changes

New: reference/authz-policy-reference.mdx

Complete reference dictionary covering:

  • Cedar entity types (Client, Action, Tool, Prompt, Resource, FeatureType, THVGroup)
  • All 6 authorization-checked actions + always-allowed and denied-by-default MCP methods
  • Principal attributes with JWT claim type mapping
  • Resource attributes per operation type (tool call, prompt get, resource read, feature list)
  • Tool annotation attributes (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) with has operator guidance and trust boundary explanation
  • Context attributes, group membership, argument preprocessing rules, URI sanitization
  • Custom static entities via entities_json
  • HTTP PDP PORC mapping, context config, and claim mappers

Updated: concepts/cedar-policies.mdx

  • Added group-based access control section with THVGroup and in operator
  • Added tool annotation policies section with has operator, annotation examples, and forbid patterns
  • Added real-world policy profiles: observe, safe-tools, tool allowlist, RBAC with annotation guardrails
  • Added annotation/group troubleshooting sections
  • Added group_claim_name to configuration fields
  • Added Next steps section (was missing)
  • Improved intro, removed duplicate ABAC example, fixed section ordering per style guide

Updated: sidebars.ts

  • Added authz-policy-reference to sidebar

Test plan

  • npm run build passes with no new warnings or broken links
  • Ran docs-review skill for editorial quality check
  • Cross-references between concept page and reference page verified bidirectional
  • Visual review of rendered pages in Vercel preview

Generated with Claude Code

The existing Cedar policies page lacked a complete dictionary of entity
types, actions, attributes, and annotations that policy authors can
reference. This adds a dedicated reference page and enhances the concept
page with annotation-based policies, group membership, real-world
profiles, and troubleshooting for the new features.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 3, 2026 18:26
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs-website Ready Ready Preview, Comment Apr 3, 2026 6:27pm

Request Review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds comprehensive documentation for ToolHive Cedar authorization policy authoring by introducing a new reference page and expanding the existing Cedar policies concept page, plus wiring the new doc into the sidebar navigation.

Changes:

  • Added a new “Authorization policy reference” page covering entity types, actions, attributes, annotations, groups, list filtering, and HTTP PDP mapping.
  • Expanded “Cedar policies” concepts doc with group-based access control, tool annotation policy patterns, and real-world policy profiles/troubleshooting.
  • Updated sidebars.ts to include the new reference page.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
sidebars.ts Adds the new authorization policy reference doc to the ToolHive sidebar.
docs/toolhive/reference/authz-policy-reference.mdx New, detailed Cedar/ToolHive authorization reference page.
docs/toolhive/concepts/cedar-policies.mdx Enhances the Cedar policies concept doc with groups/annotations/profiles and additional troubleshooting.

Comment on lines +361 to +377
List operations (`tools/list`, `prompts/list`, `resources/list`) work
differently from other operations. ToolHive always allows the list request
itself, but filters the response to include only items the caller is authorized
to access.

For each item in the list response, ToolHive runs a policy check using the
corresponding action:

| List method | Per-item check uses |
| ---------------- | ---------------------------------------------------------- |
| `tools/list` | `Action::"call_tool"` against each `Tool::"<name>"` |
| `prompts/list` | `Action::"get_prompt"` against each `Prompt::"<name>"` |
| `resources/list` | `Action::"read_resource"` against each `Resource::"<uri>"` |

This means you don't need separate list policies. Your `call_tool`,
`get_prompt`, and `read_resource` policies automatically control what appears in
list responses.
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The list-operation semantics are internally inconsistent: this section says tools/list/prompts/list/resources/list are “always allowed”, but earlier the page lists Action::"list_*" as actions that require authorization. Please clarify whether list methods are authorization-checked, and update either the actions table or this section so they match the actual behavior.

Suggested change
List operations (`tools/list`, `prompts/list`, `resources/list`) work
differently from other operations. ToolHive always allows the list request
itself, but filters the response to include only items the caller is authorized
to access.
For each item in the list response, ToolHive runs a policy check using the
corresponding action:
| List method | Per-item check uses |
| ---------------- | ---------------------------------------------------------- |
| `tools/list` | `Action::"call_tool"` against each `Tool::"<name>"` |
| `prompts/list` | `Action::"get_prompt"` against each `Prompt::"<name>"` |
| `resources/list` | `Action::"read_resource"` against each `Resource::"<uri>"` |
This means you don't need separate list policies. Your `call_tool`,
`get_prompt`, and `read_resource` policies automatically control what appears in
list responses.
List operations (`tools/list`, `prompts/list`, `resources/list`) have two
authorization steps. First, ToolHive authorizes the list request itself using
the corresponding `list_*` action. Then it filters the response to include only
items the caller is authorized to access.
For each supported list method, ToolHive performs the following checks:
| List method | Request-level action | Per-item check uses |
| ---------------- | ------------------------------- | ---------------------------------------------------------- |
| `tools/list` | `Action::"list_tools"` | `Action::"call_tool"` against each `Tool::"<name>"` |
| `prompts/list` | `Action::"list_prompts"` | `Action::"get_prompt"` against each `Prompt::"<name>"` |
| `resources/list` | `Action::"list_resources"` | `Action::"read_resource"` against each `Resource::"<uri>"` |
This means your policies can control both whether a caller may use a list
method at all and which items appear in the response. `list_*` policies govern
access to the list operation itself, while `call_tool`, `get_prompt`, and
`read_resource` policies govern the contents of list responses.

Copilot uses AI. Check for mistakes.
Comment on lines +381 to +383
If you want explicit control over list operations (for example, to allow listing
but deny individual access), you can write policies using the `list_tools`,
`list_prompts`, or `list_resources` actions against `FeatureType::` entities.
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This note suggests you can “allow listing but deny individual access” using list_tools/list_prompts/list_resources against FeatureType:: entities, but just above you state list responses are filtered per-item using call_tool/get_prompt/read_resource. Under that model, permitting list_* would not make items appear if the per-item actions are denied. Please adjust the guidance to reflect the real filtering/authorization flow (or update the per-item check description if list_* policies are actually used for filtering).

Suggested change
If you want explicit control over list operations (for example, to allow listing
but deny individual access), you can write policies using the `list_tools`,
`list_prompts`, or `list_resources` actions against `FeatureType::` entities.
If you want explicit control over whether a list operation itself is allowed,
you can write policies using the `list_tools`, `list_prompts`, or
`list_resources` actions against `FeatureType::` entities. These actions do not
override per-item filtering: items still only appear in list responses when the
corresponding `call_tool`, `get_prompt`, or `read_resource` check succeeds.

Copilot uses AI. Check for mistakes.
Comment on lines +291 to +294
### Observe profile (read-only)

Allow listing and reading MCP capabilities, but block all tool calls:

Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The “Observe profile” says it allows listing capabilities while blocking all tool calls, but elsewhere the docs state tools/list is filtered based on call_tool permissions. If that filtering is accurate, denying all call_tool will yield an empty tool list, which contradicts “see what’s available”. Consider clarifying the expected behavior and/or revising the profile to match how list filtering works.

Copilot uses AI. Check for mistakes.
Comment on lines +369 to +377
| List method | Per-item check uses |
| ---------------- | ---------------------------------------------------------- |
| `tools/list` | `Action::"call_tool"` against each `Tool::"<name>"` |
| `prompts/list` | `Action::"get_prompt"` against each `Prompt::"<name>"` |
| `resources/list` | `Action::"read_resource"` against each `Resource::"<uri>"` |

This means you don't need separate list policies. Your `call_tool`,
`get_prompt`, and `read_resource` policies automatically control what appears in
list responses.
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the entity-type table above, Resource IDs are described as Resource::"<sanitized_uri>", but this per-item list check table shows Resource::"<uri>" for resources/list. Please make the identifier format consistent (or explicitly call out that the list filter uses the sanitized form while also exposing the original URI via an attribute).

Suggested change
| List method | Per-item check uses |
| ---------------- | ---------------------------------------------------------- |
| `tools/list` | `Action::"call_tool"` against each `Tool::"<name>"` |
| `prompts/list` | `Action::"get_prompt"` against each `Prompt::"<name>"` |
| `resources/list` | `Action::"read_resource"` against each `Resource::"<uri>"` |
This means you don't need separate list policies. Your `call_tool`,
`get_prompt`, and `read_resource` policies automatically control what appears in
list responses.
| List method | Per-item check uses |
| ---------------- | ---------------------------------------------------------------------- |
| `tools/list` | `Action::"call_tool"` against each `Tool::"<name>"` |
| `prompts/list` | `Action::"get_prompt"` against each `Prompt::"<name>"` |
| `resources/list` | `Action::"read_resource"` against each `Resource::"<sanitized_uri>"` |
This means you don't need separate list policies. Your `call_tool`,
`get_prompt`, and `read_resource` policies automatically control what appears in
list responses. For resources, the per-item check uses the sanitized
`Resource` entity ID, while the original URI remains available via the
`resource.uri` attribute.

Copilot uses AI. Check for mistakes.
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