GitHub App
Editors sign in with a GitHub App. The sign-in uses the user-to-server OAuth web flow. Only users with push access to the content repository can sign in. You need one GitHub App for each site.
/admin/login on the deployed site (or Settings → GitHub in development) and select Create the GitHub App. See Quickstart. The manual steps below also work. Use them when you cannot use the admin, for example when your organization does not let you create an App from a manifest.Create the App by hand
Create the App on GitHub
Open Settings, Developer settings, GitHub Apps, New GitHub App. For an organization, open Organization settings, GitHub Apps.
Use these settings:
- Homepage URL: the URL of your site.
- Callback URL:
https://<your-site>/api/_pluto/auth/github/callback. Addhttp://localhost:3000/api/_pluto/auth/github/callbacktoo if you want to test sign-in locally. See Callback URLs. - Expire user authorization tokens: on. The session refreshes tokens that expire.
- Request user authorization (OAuth) during installation: off.
- Webhook, Active: off.
- Repository permissions: Contents read and write, Metadata read-only. For the build status, also Checks, Commit statuses, and Deployments read-only. Nothing else.
Collect the credentials
On the App page, note the App ID and the Client ID. Generate a client secret and a private key (a .pem file). The URL name of the App (github.com/apps/<slug>) is the app slug.
Install the App
Install the App on the content repository only.
Set the environment variables
Set PLUTO_GITHUB_APP_SLUG and the NUXT_PLUTO_GITHUB_* variables in .env for local use, and in your host for production. The Reference lists every variable and the private key formats.
Deploy
Deploy to a host with a server runtime. If a check fails, see Troubleshooting.
Add the build status permissions
The admin shows the build status of a save. It needs read access to Checks, Commit statuses, and Deployments. An App that the admin creates asks for them. An App created before Pluto 0.26, or by hand without them, does not have them, and the build status does not show.
- Open the App settings on GitHub, then Permissions & events.
- Under Repository permissions, set Checks, Commit statuses, and Deployments to read-only. Save.
- Open the installation of the App (Install App, then the gear icon), and accept the new permissions.
The sign-in flow
GET /api/_pluto/auth/github/login?redirect=/path. Theredirectmust be a path on this site. Any other value becomes/admin/home. The route makes astatevalue and a PKCE verifier. It saves them in a separate sealed session (pluto-github-oauth) that lives 10 minutes. Then it answers 302 to GitHub.GET /api/_pluto/auth/github/callback. The route reads and clears the saved session first, sostateworks once. It comparesstate. Then it trades the code for tokens, reads the user, and reads the repository with the user token.GET /api/_pluto/auth/sessionanswers{ user, capabilities, repo: { name, private } }, or{ user: null }. It never has a token.POST /api/_pluto/auth/logoutdeletes the cookie and answers 204.
Sign-in errors
The callback redirects to /admin/login?error=<code>. The codes are state, not_installed, forbidden, denied, and github. See Troubleshooting for the cause and the fix of each code.
Capabilities of a user
| GitHub permission | Capabilities |
|---|---|
| admin, maintain | * (all) |
| push | The read, write, publish, and delete capabilities of every registered content type. The post type is the fallback when no type is registered. |
For the built-in post type, these are posts:read_drafts, posts:publish, and posts:delete. A user with a lower permission cannot sign in.
In development with storage: 'fs', a request from your machine gets a fixed local user with *. See Reference.
GitHub still enforces the real permission on each commit, because the commit uses the user token.
The sign-in page
The sign-in page is the core /admin/login. It has one Sign in with GitHub button. It is a full page load to the login route.
Anonymous reads
An anonymous caller sees published posts only. The store reads with a server token:
NUXT_PLUTO_GITHUB_READ_TOKEN, a read-only token, when it is set.- Otherwise an installation token of the App, for this repository, with
contents: read. The code signs an App JWT and caches the token in memory until 5 minutes before it ends. - With neither, an anonymous read answers 503 and logs the cause once. The server does not fail at boot.
A signed-in user reads and writes with their own token.
GitHub Enterprise Server
See Reference.