Skip to content

Policy v2: grant-based per-repo tool permissions #35

Description

@chaodu-agent

Part of #15 (post-v0.4.0 enhancement). From review of the shipped 2a/2b policy model.

Problem

The current per-agent policy is a flat cross product — tools × repos. An agent that should be read-only on repo-A but able to create_issue on repo-B cannot be expressed; the workaround is two agent entries with two keys.

Proposal: grants

[[mcp.agents]]
id   = "my-bot"
keys = ["env:KEY_CURRENT"]

  [[mcp.agents.grants]]
  repos = ["my-org/repo-a"]
  tools = ["issue_read", "pull_request_read"]

  [[mcp.agents.grants]]
  repos = ["my-org/repo-b"]
  tools = ["issue_read", "create_issue"]
  • A tools/call must match ≥1 grant (tool ∈ grant AND resolved repo ∈ grant). Default-deny preserved.
  • Flat tools + repos remains as sugar for a single grant (fully backward compatible).
  • Optional per-grant permissions for mint-time scoping (the App mint API's permissions param is currently unused) — e.g. the repo-B grant mints with issues: write only.

Known design wrinkles (decide before building)

  1. X-MCP-Tools upstream becomes the union of granted toolstools/list shows write tools even to sessions working in read-only repos. Acceptable: the proxy-side per-call pairing check is authoritative; the header stays defense-in-depth. But the pairing is ghpool-enforced only.
  2. Token granularity vs session pinning: sessions pin one credential, and mid-session token switching is untested upstream behavior (MCP proxy Phase 0: compliance & compatibility spike (hosted endpoint contract, App tokens) #22 residual). GitHub-side scope would be the union of exact repos across grants; per-pair GitHub enforcement would require per-call credential selection or per-grant sessions — significant design work, evaluate against actual need.
  3. Deny-if-unresolvable semantics generalize cleanly (a call with no repo target matches no repo-restricted grant).

Prior art in-tree

  • scope_envelope() (per-agent union scoping) and repo_allowed() in src/policy.rs are the extension points.
  • Audit records already carry (agent, tool, repo) — grants add a grant id to the record for traceability.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions