Skip to content

Add a read_tool action so Cedar can grant tools/list visibility without invocation #6924

Open

Description

@rkb32

Current behavior

Cedar only checks call_tool. A tool appears in tools/list only when a call_tool policy allows it, so a policy cannot grant visibility alone.

Wanted

A read_tool action, so a policy can list a tool without allowing it to be called.

Where

pkg/authz/authorizers/cedar/core.go: AuthorizeWithJWTClaims has no tool/read case. The read check currently returns an "unsupported" error, which is ignored, and the tool:call check decides.

Depends on #6903 (tool:call implies tool:read).

I found this while reviewing #6903. I'd like to work on it if a maintainer agrees it's worth doing. Could you assign it to me once you've had a look? Thanks.

Activity

  1. jhrozek commented on Oct 22, 2026

    @jhrozek
    Contributor

    Thanks for writing this up. Before anyone starts on it, there's a catch. A real read_tool action changes what some existing policies do, so it isn't purely additive.

    Take this policy set:

    permit(principal, action, resource);
    forbid(principal, action == Action::"call_tool", resource == Tool::"t");
    

    Today tools/list asks about call_tool, so the forbid applies and t is hidden. With #6903 as it stands it's still hidden, because the Cedar read check errors and the call check decides. If Cedar evaluated Action::"read_tool", the read request would match the broad permit and not the call-only forbid, so t would be listed. I checked this against the real Cedar authorizer. The same goes for unless { action == Action::"call_tool" } and any forbid that only looks at call context.

    Action groups don't get us out of it. With read_tool in call_tool, policies written as action == Action::"call_tool" still never match a read request, because == is exact. With call_tool in read_tool, a read grant would allow calls.

    So I think this needs a short design first. It should say what a call-only forbid should mean for visibility, and how existing deployments get through the change: opt-in, a migration note, or something else. Happy to look at a proposal here before any code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions