Every engineering team we have talked with during early access asks the same first question: what does this app read? It is the right question. You are granting a third-party system access to your production codebase. The permission screen that GitHub shows you during app installation lists a set of capabilities, but it does not tell you which ones are actually used and which ones are requested because it is easier to over-provision than to go back and ask for more later.
This post is a complete walkthrough of every permission the Codepylon GitHub App requests, what we use each one for, and what we explicitly do not request. We also explain the GitHub App model itself for teams who have not worked with it before, because understanding the model makes the permission scope less opaque.
How GitHub Apps work, briefly
A GitHub App is different from an OAuth application. OAuth apps act as the installing user and inherit their permissions. GitHub Apps have their own identity and request specific permissions that are scoped to specific repositories the team chooses during installation. When you install the Codepylon GitHub App, you choose which repositories it can access. It cannot see your other repositories, your organization settings outside what is explicitly permitted, or your personal account details.
Within the chosen repositories, the App holds an installation token that expires every hour. Long-lived tokens that could be exfiltrated and used indefinitely are not a concern with the GitHub App model; each action requires a fresh token generated from the app's private key. That private key never leaves Codepylon's infrastructure.
Permissions we request: read
Contents (read): this is the core permission that lets Pylon index your repository. Without read access to repository contents, there is no context graph and no agent job. Pylon reads file contents during indexing and during job execution to understand the code it is changing. We do not cache raw file content beyond the duration of the job; the context graph stores structural information (the graph metadata and properties), not source text.
Metadata (read): required by GitHub for all GitHub Apps. This covers repository name, description, default branch, and visibility. We use it to correctly identify which repository a job belongs to and to read the default branch name for PR targeting.
Pull requests (read): used to read existing PRs when Pylon needs to understand the current PR state before creating a new one, and to read review comments when responding to feedback in the review loop.
Statuses (read): used to read CI check results after a PR is opened. Pylon monitors status checks to know whether the tests it expected to pass are actually passing, and to detect CI failures that might indicate its changes need revision.
Issues (read): used only for repositories where issues are used as the primary ticket tracking mechanism (rather than Jira or Linear). When an issue is linked to a Pylon job, this permission lets Pylon read the issue title and description for context.
Permissions we request: write
Contents (write): used to create the branch for a Pylon job and to push the diff commits. Without this, Pylon cannot open a PR. The write permission is scoped to the branch Pylon creates; it does not allow writes to your main or protected branches. Branch protection rules you have configured remain in effect.
Pull requests (write): used to open the PR and to post the PR description. Also used when Pylon responds to review comments and revises the PR: updating the description, requesting re-review, and posting clarifying comments when a reviewer asks a question Pylon can answer from the code context.
Statuses (write): used to post Pylon's own status check on PRs it opens. When a Pylon job is running validation, we post a status check so reviewers can see the job is in progress. This is the same mechanism that CI systems use to post build results.
What we do not request
The absence of certain permissions is as important as what is listed. We do not request administration, organization, secrets, environments, actions (write), or deployments write access.
Administration access would let the App modify repository settings, add or remove collaborators, and change branch protection rules. Pylon has no need for any of these. If we ever needed to suggest a branch protection rule change (for example, if a job determined that a protection rule was preventing a legitimate merge), we would surface that as a recommendation in the PR description, not execute it automatically.
Secrets access would let the App read repository secrets and environment variables. Pylon does not need to know your API keys, database credentials, or any other secrets. We do not want this access. If a job requires knowledge of a configuration value to make a correct code change, that information should come from the job specification or a dedicated secrets management tool, not from reading the repository secrets directly.
Actions write access would let the App modify or create GitHub Actions workflows. Pylon can suggest workflow changes in a PR description, but does not write to .github/workflows/ unless that is explicitly the subject of a job.
Repository selection during installation
During installation, GitHub asks whether to grant access to all repositories or specific ones. We strongly recommend selecting specific repositories, starting with one or two repositories where you want to run initial Pylon jobs. You can always add more repositories later from the GitHub App settings. Starting narrow makes the initial review easier and builds confidence in what the app is and is not touching before you expand the scope.
If your organization uses GitHub Enterprise Server rather than GitHub.com, the installation process is slightly different and requires an additional configuration step on the Codepylon side to point to your server's API endpoint. We cover this in the documentation, but it is worth flagging upfront: the self-hosted version of the GitHub App is not automatically available; you need to contact us to set it up.
The permission scope documented here reflects the current version of the app. When we need additional permissions in the future, we will request them explicitly through GitHub's standard permission update flow, which requires an organization admin to approve the change. We do not expand permissions silently.