Skip to content

[SPIKE] Expand FGP per-tool permission annotations + consolidate docs#2679

Draft
SamMorrowDrums wants to merge 5 commits into
sammorrowdrums/fgp-requirementsfrom
sammorrowdrums/fgp-expand-permission-annotations
Draft

[SPIKE] Expand FGP per-tool permission annotations + consolidate docs#2679
SamMorrowDrums wants to merge 5 commits into
sammorrowdrums/fgp-requirementsfrom
sammorrowdrums/fgp-expand-permission-annotations

Conversation

@SamMorrowDrums

@SamMorrowDrums SamMorrowDrums commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Note

Stacked on #2676. Base branch is sammorrowdrums/fgp-requirements, not main. Review #2676 first. This PR only adds per-tool RequiredPermissions annotations and the docs they generate — it changes no runtime behaviour.

What this does

Expands the per-tool fine-grained-permission (FGP) RequiredPermissions annotations introduced by #2676 across the clearly-mappable tools, then regenerates the docs that are built from those annotations.

The pipeline is the same as the existing scope-filtering docs:

annotate ServerTool definitions (source of truth)
        │
        ▼
script/generate-docs  →  docs/permissions-filtering.md  (between the
                          <!-- START/END AUTOMATED PERMISSIONS --> markers)
  • The single source of truth is each tool's .WithPermissions(permissions.Require(...)) annotation on its ServerTool.
  • The table in docs/permissions-filtering.md is generated, never hand-edited. Re-running the generator is idempotent (zero diff on a second run).
  • The list-permissions CLI reads the same inventory, so it stays consistent with the table.
  • Per-tool FGP clutter was removed from the README/tool docs; a static NOTE (outside the generated markers) links to docs/permissions-filtering.md.

How the permissions were verified

Per-tool requirements were verified against the GitHub REST docs' embedded fine-grained permissions — the rendered "The fine-grained token must have the following permission set: …" line on each endpoint's docs page (from the page's progAccess.permissions). Only the public OpenAPI (api.github.com.json) omits this data; the docs pages carry it, so they are the source used here. Only GraphQL-only tools (ProjectsV2, issue-fields) lack a docs-REST source and remain best-guess or ungated.

Semantics (from #2676): a requirement is an OR of AND-sets. permissions.Require(a, b) is a single AND-set (the token needs a and b). Reads map to *:read, mutations to *:write.

Guardrails held: only consts that exist in pkg/permissions/catalog_generated.go are used (none invented); the catalog itself is not regenerated (that hits the network — #2676 owns it); genuinely non-FGP tools stay ungated.

Authoritative (verified against the REST docs' embedded permissions)

Toolset Tool Permission
actions actions_get, actions_list, get_job_logs actions:read
actions actions_run_trigger actions:write
code_security get_code_scanning_alert, list_code_scanning_alerts security_events:read
context get_teams, get_team_members members:read
dependabot get_dependabot_alert, list_dependabot_alerts vulnerability_alerts:read
discussions get_discussion, get_discussion_comments, list_discussions, list_discussion_categories discussions:read
discussions discussion_comment_write discussions:write
git get_repository_tree contents:read
issues issue_read, list_issues, get_label issues:read
issues issue_write, add_issue_comment, sub_issue_write issues:write
labels list_label, get_label issues:read
labels label_write issues:write
pull_requests pull_request_read, list_pull_requests pull_requests:read
pull_requests create_pull_request, update_pull_request, pull_request_review_write, add_comment_to_pending_review, add_reply_to_pull_request_comment, update_pull_request_branch pull_requests:write
pull_requests merge_pull_request contents:write
repos get_file_contents, get_commit, list_commits, list_branches, list_tags, get_tag, list_releases, get_latest_release, get_release_by_tag contents:read
repos create_or_update_file, push_files, delete_file, create_branch contents:write
repos list_repository_collaborators metadata:read
repos create_repository administration:write
repos fork_repository administration:write AND contents:read
secret_protection get_secret_scanning_alert, list_secret_scanning_alerts secret_scanning_alerts:read
stargazers list_starred_repositories starring:read
stargazers star_repository, unstar_repository starring:write

Notes on the two asymmetric PR endpoints and the repo-management ones (all docs-verified):

  • merge_pull_requestContents:write only (docs "Merge a pull request"; pull_requests:write is not required, so requiring it would over-hide the tool for a contents-only token).
  • update_pull_request_branchPull requests:write only (docs "Update a pull request branch"; contents:write not required).
  • list_repository_collaboratorsMetadata:read (docs "List repository collaborators").
  • create_repositoryAdministration:write (POST /user/repos and POST /orgs/{org}/repos).
  • fork_repositoryAdministration:write AND Contents:read (docs "Create a fork").
  • star_repository / unstar_repositorystarring:write. (Docs also list Metadata:read, omitted here as the universal baseline — consistent with the rest of the set, which doesn't spell out implicit metadata:read.)

Best-guess (one entry, flagged for review)

Tool Permission Why it's a guess
list_issue_fields issues:read GraphQL-backed (Projects/issue-field API); no REST docs page with embedded FGP to verify against. issues:read is the closest catalog const. Feature-flag-gated, so it appears in list-permissions --toolsets=all but not in the docs table.

Intentionally ungated (no clear public FGP mapping)

Tool(s) Reason
projects_get, projects_list, projects_write ProjectsV2 is GraphQL with no REST docs endpoint to verify; the classic organization_projects const is a poor fit (deprecated, wrong scope shape).
search_* (search_code, search_issues, search_pull_requests, search_repositories, search_users, search_orgs, search_commits) Cross-cutting search; works with baseline token.
get_me Identity/context baseline.
assign_copilot_to_issue, request_copilot_review Copilot / plan-gated, not FGP.
create_gist, get_gist, list_gists, update_gist No matching catalog const for gists.
list_notifications Cross-cutting; notifications const not in catalog.
list_global_security_advisories, get_global_security_advisory, list_repository_security_advisories, list_org_repository_security_advisories Global/public advisory data; no matching catalog const.
list_issue_types Org metadata with no clear FGP mapping.

Validation

  • go build ./...
  • script/generate-docs ✅ — table is 55 rows; second run produces zero diff (idempotent).
  • bin/golangci-lint run ./pkg/github/... ./cmd/... ✅ — 0 issues.
  • go test -race ./... ✅ — all packages pass.

SamMorrowDrums and others added 5 commits June 12, 2026 19:24
Expand RequiredPermissions annotations across the remaining
clearly-mappable tools (discussions, git, issues, labels, pull
requests, repositories/stargazers, and the granular issue/PR write
tools) so the generated fine-grained-permission table in
docs/permissions-filtering.md is comprehensive.

Stop rendering the per-tool "Required Permissions (fine-grained)" line
in the large generated tool listings (README, feature-flags.md,
insiders-features.md): it cluttered those listings. The consolidated
requirement table now lives solely in docs/permissions-filtering.md,
and the README Tools section links to it.

Permission catalog and tool behaviour are unchanged; only annotations
and generated docs are affected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Annotate the remaining clearly-mappable tools with RequiredPermissions and
regenerate the permissions docs table from the tool definitions:

- repos: create_repository, fork_repository (administration:write);
  list_repository_collaborators (administration:read)
- context: get_teams, get_team_members (members:read)
- projects: projects_get/list (organization_projects:read),
  projects_write (organization_projects:write)
- issues: list_issue_fields (issues:read)

list_issue_types stays ungated (org-level issue-type config has no clean
repo/org catalog permission). Docs table grows 50->58 rows and is idempotent.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- list_repository_collaborators: administration:read -> metadata:read
  (the list endpoint requires Fine-grained Metadata read; administration
  only covers adding/removing collaborators)
- create_repository, fork_repository: revert to ungated (administration
  mapping is genuinely ambiguous between user- and org-owned repos)
- projects_get/list/write: revert to ungated (ProjectsV2 GraphQL does not
  map cleanly to the classic repository_projects/organization_projects
  catalog consts)

get_teams/get_team_members keep members:read; list_issue_fields keeps
issues:read. Docs table regenerated (idempotent).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The collaborators list endpoint requires write/maintain/admin repo
privileges (and read:org for classic tokens), so it is not a
low-privilege metadata read. administration:read is the better-grounded
best-guess. Docs table regenerated (idempotent).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Verify per-tool fine-grained permissions against the GitHub REST docs'
embedded permission sets (progAccess.permissions):

- merge_pull_request: contents:write only (was contents:write AND
  pull_requests:write)
- update_pull_request_branch: pull_requests:write only (was contents:write
  AND pull_requests:write)
- list_repository_collaborators: metadata:read (was administration:read)
- create_repository: re-add administration:write
- fork_repository: re-add administration:write AND contents:read

Regenerate docs/permissions-filtering.md (55 rows; idempotent).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

1 participant