Skip to content

docs: document required GitHub App permissions and PAT scopes#416

Merged
jmeridth merged 1 commit into
mainfrom
docs/document-required-permissions
Jun 6, 2026
Merged

docs: document required GitHub App permissions and PAT scopes#416
jmeridth merged 1 commit into
mainfrom
docs/document-required-permissions

Conversation

@jmeridth

@jmeridth jmeridth commented Jun 3, 2026

Copy link
Copy Markdown
Collaborator

Pull Request

Proposed Changes

Added a Required GitHub App permissions subsection under the GitHub App Installation auth table that lists the exact permissions the action needs:

  • Repository → Metadata: Read
  • Repository → Contents: Read & write
  • Repository → Pull requests: Read & write
  • Organization → Members: Read

Added a corresponding Required PAT scopes subsection covering both classic (repo, read:org) and fine-grained PAT setups, and corrected the GH_TOKEN field description that previously said "Must have read access to all repository you are interested in scanning" — the action also opens PRs, so read-only is insufficient.

Why

Until now the README left users to discover required permissions by trial and error. When any required permission is missing, the action fails with Error: 403 Resource not accessible by integration on the first API call that needs it, which is opaque and hard to map back to a specific App or PAT setting. Documenting the explicit permission set up front cuts that debugging loop. Also helps installation owners know they need to accept the new permission request on the org installation after the App definition is updated.

Testing

  • Verified each permission against the actual API calls in cleanowners.py:
    • gh_org.is_member(username) → Organization Members: Read
    • repo.file_contents(...) / repo.blob(...) → Repository Contents: Read
    • repo.create_ref(...), repo.create_file(...), file_contents.update(...) → Repository Contents: Write
    • repo.create_pull(...) → Repository Pull requests: Write
  • Reproduced the 403 in a downstream consumer (App had Contents: Read only); after granting Contents: Write on the App and accepting the installation's new permission request, the next workflow run succeeded.
  • make test → 74 tests pass with 100% coverage
  • markdownlint-cli2 --config .github/linters/.markdown-lint.yml README.md → 0 errors

Readiness Checklist

Author/Contributor

  • If documentation is needed for this change, has that been included in this pull request
  • run make lint and fix any issues that you have introduced
  • run make test and ensure you have test coverage for the lines you are introducing

## What

Added a "Required GitHub App permissions" subsection under the GitHub App
Installation auth table listing the Contents read/write, Pull requests
read/write, Metadata read, and Organization Members read permissions the
action actually needs. Added a corresponding "Required PAT scopes"
subsection clarifying the classic and fine-grained PAT scopes, and
corrected the PAT field description that previously implied read-only
access was sufficient.

## Why

Until now the README left users to discover the required permissions by
trial and error. When any required permission is missing, the action fails
with "403 Resource not accessible by integration" on whichever API call
needed it, which is opaque and hard to map back to a specific App or PAT
setting. Documenting the explicit permission set up front cuts that
debugging loop and removes a recurring source of issues.

## Notes

- Permissions list was derived from the action's actual API calls in
  cleanowners.py (gh_org.is_member, repo.create_ref / create_file / update,
  repo.create_pull) — verifying any future call additions may shift the
  required permission set.
- The PAT description fix may surprise users who read the old line as a
  hint that a read-only PAT could be used; the doc now explicitly tells
  them otherwise.
- No code, tests, or workflow files changed — README only.

Signed-off-by: jmeridth <jmeridth@gmail.com>
@jmeridth jmeridth added the Mark Ready When Ready Automatically mark draft PR ready when checks pass label Jun 3, 2026
@jmeridth jmeridth self-assigned this Jun 3, 2026
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Jun 3, 2026
@jmeridth jmeridth marked this pull request as ready for review June 3, 2026 16:09
@jmeridth jmeridth requested a review from zkoppert as a code owner June 3, 2026 16:09
@github-actions github-actions Bot removed the Mark Ready When Ready Automatically mark draft PR ready when checks pass label Jun 3, 2026
@zkoppert zkoppert requested a review from Copilot June 6, 2026 16:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR improves the action’s user-facing documentation by explicitly listing the GitHub App permissions and PAT scopes required for the action to successfully read/update CODEOWNERS content and open pull requests, reducing “403 Resource not accessible by integration” trial-and-error setup.

Changes:

  • Documented the exact required GitHub App permissions (repo metadata/contents/PRs and org members).
  • Documented required classic and fine-grained PAT scopes, and updated GH_TOKEN’s description to point to those requirements.
Show a summary per file
File Description
README.md Adds explicit GitHub App permission requirements and PAT scope guidance; clarifies GH_TOKEN expectations.

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 1

Comment thread README.md
- **Repository → Pull requests**: Read & write — open PRs that suggest CODEOWNERS changes
- **Organization → Members**: Read — check whether each CODEOWNERS entry is still an organization member

If any of these are missing the action fails with `Error: 403 Resource not accessible by integration` on the first API call that needs the missing permission. Updating an existing App's permissions also requires the installation owner to accept the new permission request before it takes effect.
Comment thread README.md
App must be granted these permissions:

- **Repository → Metadata**: Read (default)
- **Repository → Contents**: Read & write — read CODEOWNERS files; create branches and commit the placeholder CODEOWNERS file when one is missing

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Nice catch on the read-only-token correction in the GH_TOKEN row -- that's been wrong for a while and worth fixing on its own.

One small thing on the Contents: Write rationale:

Suggested change
- **Repository → Contents**: Read & write — read CODEOWNERS files; create branches and commit the placeholder CODEOWNERS file when one is missing
- **Repository → Contents**: Read & write — read CODEOWNERS files; create branches and commit changes (updating existing CODEOWNERS files to remove members and creating the placeholder file when one is missing)

I believe Contents: Write is required for the primary use case too, not just the "missing CODEOWNERS" path. commit_changes() is called from two sites in cleanowners.py -- the missing-CODEOWNERS branch (around L155) and the existing-CODEOWNERS branch that removes members (around L229) -- and both unconditionally hit repo.create_ref() plus repo.create_file() / file_contents.update(). A reader landing on the current wording could reasonably conclude they can skip Write if their repos already have CODEOWNERS files, then get 403s on the first run.

@jmeridth jmeridth merged commit c2a0277 into main Jun 6, 2026
38 checks passed
@jmeridth jmeridth deleted the docs/document-required-permissions branch June 6, 2026 23:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants