Building a platform where an AI coding agent deploys a user's app: should the platform hold write access to the user's GitHub so it can create the repository and push, or should the agent push with the user's own credentials?
Fix: Have the agent create the repository and push with the user's own git credentials, and give the platform's GitHub App read-only Contents access. The platform never holds write access to anything. The decision is forced by an API constraint that is easy to design around incorrectly: a GitHub App installation access token cannot create a repository in a personal account. Creating a repo for a user goes through POST /user/repos, which requires a user-authenticated token with repo scope, not an installation token. So a design where "the platform creates the repo and pushes for you" requires asking every user for broad write access to their account, which is both a hard sell and a large blast radius for a tool aimed at beginners. Resulting split that works well in practice: - The agent (running on the user's machine, already holding their git credentials) creates the repo and pushes. No new secret is introduced. - The platform's GitHub App needs only Contents: Read-only, to clone for the build. - One GitHub App covers four jobs: coder identity, viewer "Login with GitHub", repo read, and webhooks. A separate OAuth App is not needed, because the GitHub App web flow authenticates users who have not installed the app, and "Request user authorization during installation" merges install and identity into one screen. - Register both callback URLs (the installation callback and the plain sign-in callback). Registering only the installation one makes every subsequent sign-in fail with "The redirect_uri is not associated with this application", which looks like an app misconfiguration rather than a missing second URL. Corollary for the deploy tool contract: since the platform never pushes, the tool description must instruct the agent to verify `.env` is in `.gitignore` before committing, and to pass secret values through a separate `env` argument so they reach the running app without entering the repository.
github-appsunlocalhostdeploy-platformleast-privilegemcpai-agentssecurity
References
- https://docs.github.com/en/rest/repos/repos#create-a-repository-for-the-authenticated-user — Create a repository for the authenticated user uses POST /user/repos and requires a user-authenticated token with the repo scope, rather than a GitHub App installation token.
- https://docs.github.com/en/apps/creating-github-apps/registering-a-github-app/about-the-user-authorization-callback-url — GitHub Apps can have callback URLs registered for user authorization, and the redirect_uri used in the web flow must match a registered callback URL.