Skip to content

Model OAuth scope policies - #3128

Open
SamMorrowDrums wants to merge 1 commit into
mainfrom
sammorrowdrums-scope-policy-model
Open

Model OAuth scope policies#3128
SamMorrowDrums wants to merge 1 commit into
mainfrom
sammorrowdrums-scope-policy-model

Conversation

@SamMorrowDrums

@SamMorrowDrumsSamMorrowDrums commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

Give each tool one explicit OAuth scope policy instead of flattening scopes into lists.

A policy describes:

  • alternative ways to authorize a call;
  • scopes that must be held together;
  • broader scopes that may satisfy one requirement;
  • the scope to request when a requirement is missing.

Tools may resolve a more specific policy from call arguments before an OAuth challenge.

Why

A flat list cannot distinguish repo OR read:org from repo AND workflow. That caused two opposite problems: PAT filtering could show tools a token could not use, while stricter interpretations could hide tools or request scopes the chosen operation did not need.

What changed

  • Added the policy model as the only tool-scope API.
  • Migrated every tool registration to an explicit policy.
  • Resolved repository-vs-organization access for list_issue_fields, list_issue_types, and ui_get from their arguments.
  • Required repo and workflow only for workflow-file writes.
  • Kept repository deletion on repo and delete_repo together.
  • Updated PAT filtering, OAuth challenges, list-scopes, and generated tool docs to use the same policy.
  • Kept file paths in the parsed MCP body rather than projecting them into headers.

Related work

Supersedes #2778 and #3092.

CopilotAI balanced review requested due to automatic review settings August 20, 2026 15:20
@SamMorrowDrums
SamMorrowDrums requested a review from a team as a code ownerAugust 20, 2026 15:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Introduces explicit OAuth authorization policies with alternative paths, conjunctive requirements, and argument-aware scope resolution.

Changes:

  • Adds policy modeling, evaluation, hierarchy traversal, and compatibility projection.
  • Resolves scopes dynamically for repository/org operations and workflow-file writes.
  • Adds path validation, middleware integration, documentation, and tests.
Show a summary per file
FileDescription
pkg/scopes/scopes.goImplements policy construction and evaluation.
pkg/scopes/scopes_test.goTests policy semantics and hierarchy expansion.
pkg/scopes/map.goMaps and resolves tool scope policies.
pkg/scopes/map_test.goTests call-specific policy resolution.
pkg/inventory/server_tool.goAdds policy metadata to tools.
pkg/inventory/server_tool_test.goVerifies path headers are excluded.
pkg/http/middleware/scope_challenge.goApplies resolved policies to OAuth challenges.
pkg/http/middleware/scope_challenge_test.goTests argument-aware challenges.
pkg/github/ui_tools.goAdds a scope resolver to ui_get.
pkg/github/tool_scopes.goDefines repository/org and UI policies.
pkg/github/tool_scopes_test.goTests conditional tool policies.
pkg/github/scope_filter.goFilters tools using authorization paths.
pkg/github/scope_filter_test.goTests compatibility and fail-open behavior.
pkg/github/repository_path.goValidates paths and detects workflow writes.
pkg/github/repository_path_test.goTests path safety and workflow policies.
pkg/github/repositories.goApplies validation and dynamic write policies.
pkg/github/issues.goAdds issue-type scope resolution.
pkg/github/issue_fields.goAdds issue-field scope resolution.
pkg/github/header_params_test.goEnsures paths remain in MCP arguments.
pkg/github/dependencies.goInitializes legacy-compatible policies.
docs/scope-filtering.mdDocuments the policy model.

Review details

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 21/21 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment on lines +37 to +42
switch method {
case "labels", "assignees", "milestones", "branches", "issue_fields", "reviewers":
if repo, ok := arguments["repo"].(string); ok && repo != "" {
return scopes.AllOfScopePolicy(scopes.Repo)
}
}
Comment on lines +61 to +78
for _, file := range files {
fileMap, ok := file.(map[string]any)
if !ok {
return scopes.UnscopedScopePolicy()
}
value, ok := fileMap["path"].(string)
if !ok {
return scopes.UnscopedScopePolicy()
}
cleaned, err := validateRelativePath(value)
if err != nil {
return scopes.UnscopedScopePolicy()
}
if isWorkflowPath(cleaned) {
return scopes.AllOfScopePolicy(scopes.Repo, scopes.Workflow)
}
}
return scopes.AllOfScopePolicy(scopes.Repo)
@SamMorrowDrums
SamMorrowDrumsforce-pushed the sammorrowdrums-scope-policy-model branch from 442d43f to 96f14fdCompareAugust 21, 2026 00:16
@SamMorrowDrumsSamMorrowDrums changed the title Model alternative OAuth scope policiesModel OAuth scope policiesAug 21, 2026
Model authorization as alternative paths with conjunctive requirements and
per-requirement scope alternatives. Resolve call-specific policies from tool
arguments for precise PAT filtering and OAuth challenges.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 26e41558-43f9-42b2-8569-8489957c2b0a
@SamMorrowDrums
SamMorrowDrumsforce-pushed the sammorrowdrums-scope-policy-model branch from 96f14fd to 05d9ff1CompareAugust 21, 2026 00:18
Sign up for freeto 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

@SamMorrowDrums