Authorization server: narrow a JWT-bearer access token to one MCP call with authorization_details

未关闭
#7,061 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
35/100
Issue 类型
功能
描述清晰度
基本清楚
活跃度
活跃
技术栈
go

调研方向

Start at the authorization server’s RFC 7523 JWT-bearer grant handling and token issuance path; the issue does not name files or tests. Read RFC 9396 and the linked #6886, #6887, and #7030 for the surrounding requirements, then trace how client token lifetimes are configured. Done means the acceptance cases pass, including rejection reasons, narrowing, per-client lifetime, and unchanged behavior without authorization_details.

由索引模型根据 Issue 内容生成。

描述

needs-triage

Part of #6886. Related: #6887 (returns the granted authorization_details in the token response; does not accept or narrow a request), #6909, #6910, #6912.

Problem: a client that redeems an ID-JAG at the gateway's authorization server (RFC 7523 JWT-bearer grant) gets an access token good for any call to the resource until it expires. A client that sends tool calls on behalf of a separate, more trusted authorizer (Mecatl: the harness sends the call, its identity broker authorizes it and redeems the ID-JAG) should hold a token that serves only the call the authorizer approved. Today the token cannot be narrowed to one call.

Today: the server already parses the authorization_details entry, but keeps it out of the issued JWT.

Change: on the JWT-bearer grant, accept an RFC 9396 authorization_details request with one entry of a new type, and copy it into the issued access token.

  • Entry type https://toolhive.dev/mcp_tool_call, one of:
    • a tool call: server, tool (the name the vMCP routes by, as in params.name), arguments_sha256 (lowercase hex SHA-256 of the RFC 8785 serialization of params.arguments, or of {} when absent), operation_id;
    • a list call: server, method (tools/list or another list method).
  • Narrowing only: the entry can only restrict the token, never widen what the grant, client, or resource would otherwise allow. Exactly one entry; a malformed entry, an unknown field, or more than one entry is refused with invalid_authorization_details (RFC 9396 §5).
  • In the token: the entry is copied unchanged into the access token's authorization_details claim, and returned in the token response (with #6887).
  • Lifetime per client: a configurable access-token lifetime for a client (here, Mecatl's mecatl client), so these tokens can live seconds while other clients keep the default.
  • Reason code: refusals carry a reason code in error_description, in the grammar of #7030.

Acceptance:

  • a JWT-bearer redemption with a valid tool-call or list-call entry returns a token whose authorization_details equals the requested entry;
  • a malformed entry, two entries, or an unknown type is refused with invalid_authorization_details and its reason;
  • the entry never adds a resource, scope, or audience the redemption would not otherwise grant;
  • a client with a configured lifetime gets tokens with that lifetime; other clients are unaffected;
  • a redemption without authorization_details behaves exactly as today.

Context: Mecatl agent identity design, credentials-and-lifecycle.md step (8) ("The argument hash") and implementation.md "ToolHive work list". Tracked in stacklok/mecatl#2570 (phase 2).

主要语言
Go
星标
2.3k
派生
326
平均合并
22 小时 47 分钟
30 天内合并 PR
162

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

stacklok/toolhive 的其他 Issue

查看 stacklok/toolhive 的全部 Issue

相似的 Issue

更多 Go Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。