Connect to GitHub
Rennet talks to GitHub directly from your machine, as you. Its first choice of
credential is the one your terminal already uses: the GitHub CLI. If gh pr view
works for you, Rennet works — including on enterprise and SSO organizations.
There is no Rennet backend in the path.
You only need GitHub access to review pull requests or post a review. Reviewing your own local working tree needs no GitHub account.
The GitHub CLI is the primary path
Section titled “The GitHub CLI is the primary path”When a command needs GitHub, Rennet asks the installed gh for its token
(gh auth token) and uses it for that request. This piggybacks your own
authorization, including SSO: an organization that has approved the GitHub CLI
has already approved the path Rennet rides.
This matters because the alternative structurally cannot reach those
repositories. An OAuth app’s token only sees an organization’s repos if the app
is authorized on that organization, and enterprise policies usually forbid
members from granting that. Your gh token carries your own access instead.
A gh-sourced credential has no Rennet-side lifecycle: gh owns sign-in,
refresh, and revocation. If gh is signed out, run gh auth login in a
terminal; Rennet picks the credential up on the next GitHub request.
Settings → Environments → GitHub account labels this state GitHub CLI. It
shows the connected account but no Rennet Disconnect button, because Rennet
has no credential to delete. Run gh auth logout in the project environment when
you want to sign that CLI out.
SSO organizations that restrict the GitHub CLI
Section titled “SSO organizations that restrict the GitHub CLI”gh auth login signs you in through the GitHub CLI’s OAuth app. Many enterprise
organizations restrict OAuth apps, and until an organization owner approves the
GitHub CLI, its token cannot see that organization’s repositories. A member
cannot approve it themselves. Fine-grained tokens are often restricted in the
same way.
A classic personal access token works without an owner’s approval:
- On GitHub, open Settings → Developer settings → Personal access tokens →
Tokens (classic) and generate a token with the
repoandworkflowscopes. - In the token list, choose Configure SSO next to the token and authorize the organization.
- Run
gh auth login --with-tokenand paste the token. This stores it as the GitHub CLI’s own credential, so Rennet uses it even when it is launched from the Dock or Start menu and cannot see your shell’sGITHUB_TOKEN. - Check with
gh repo view <owner>/<name>, then refresh New Chat.
Device sign-in, the fallback
Section titled “Device sign-in, the fallback”When Rennet cannot resolve a gh binary in the environment, it offers its own
sign-in through GitHub’s OAuth device flow. Settings calls this GitHub fallback
so it cannot be mistaken for the primary CLI path. Rennet stores one credential
in a private file on disk and uses it for GitHub requests.
Once Rennet resolves a gh binary, that source stays authoritative when its token
command fails, GitHub rejects its credential, or it lacks a required scope. Rennet
shows the corresponding gh auth status, gh auth login, or gh auth refresh
repair instead of silently switching to a different fallback identity.
- Choose Use fallback sign-in. Rennet asks GitHub for a device code and shows you a short one-time user code.
- Open
github.com/login/device, enter the code, and authorize the Rennet OAuth app for your account. - Rennet polls GitHub in the background until you authorize, then stores the token.
The user code expires after about fifteen minutes; if it lapses, start again.
The Rennet OAuth app uses a public client id and no client secret, and every
request in the exchange goes from your machine to github.com.
Know the fallback’s limit: a device-flow token cannot see an organization’s
repositories unless that organization has authorized the Rennet OAuth app, which
enterprise app policies commonly prevent. If an organization repo works in your
terminal but not in Rennet, install and authenticate gh so Rennet can use the
same approved path.
What the token can do
Section titled “What the token can do”The device sign-in requests two scopes:
reporeads and writes the repositories your account can already reach, so Rennet can read a pull request and post your review. Classic OAuthrepoaccess is account-wide, not a per-repository pick.workflowis requested alongsidereposo a token-authenticated request that touches files under.github/workflows/is not rejected. Your coding agent’s branch push uses git’s own credentials, not this token.
Whatever its source, the token acts as you: it can do only what your GitHub account can already do.
Where the fallback token lives
Section titled “Where the fallback token lives”A gh credential stays wherever gh keeps it; Rennet stores nothing. The
device-flow fallback stores one credential as a single file named
github-token in the daemon’s data directory, with owner-only (0600)
permissions. Anyone who can read that file can act as you on GitHub until you
disconnect.
Rennet keeps all of its state in one directory, ~/.rennet, on every platform,
so the credential is at ~/.rennet/github-token. Pass --data-dir (or set
RENNET_USER_DATA) to put it somewhere else.
On Windows with a WSL project, the daemon runs inside the distro and keeps the token there. See Windows and WSL.
The token stays on the host. It never enters your project files, never gets staged or committed, and is never sent to the desktop, browser, or mobile client that shows your review. Rennet stores no other GitHub secret.
Refresh and expiry
Section titled “Refresh and expiry”gh-sourced tokens have no Rennet refresh story — gh handles its own.
For the device-flow fallback: if the OAuth app is configured for expiring user tokens, GitHub mints an eight-hour access token plus a longer-lived refresh token, and Rennet rotates the pair for you shortly before expiry or right after GitHub rejects a call as expired. When GitHub declines a refresh because the refresh token expired, rotated, or was revoked, Rennet reports that you need to sign in again.
Use a personal access token instead
Section titled “Use a personal access token instead”Settings → Environments → GitHub account also offers Fallback access token
when no GitHub CLI binary is available in that environment. Paste a personal
access token and Rennet validates it against GitHub before storing it, so a bad
paste saves nothing. A personal access token has no refresh half; Rennet uses it
as-is until you replace or disconnect it. Give it the repo and workflow
scopes.
Disconnect
Section titled “Disconnect”For a fallback connection, Settings → Environments → GitHub account shows
Disconnect. It deletes the fallback token file; Rennet keeps no copy. A gh
connection has no Rennet Disconnect button and is signed out with
gh auth logout, since its credential was never Rennet’s. Reviewing your local
working tree keeps working; anything that needs GitHub prompts for a credential
again.
When something is wrong
Section titled “When something is wrong”Rennet separates the failure states so you know what to fix:
- Not connected: no
ghbinary was resolved and the fallback store is empty. Makeghavailable in that environment, or use the device sign-in. - Token invalid: a CLI credential could not be read or was rejected, or a fallback credential was revoked. Follow the source-specific repair shown in the app.
- Insufficient scope: the token lacks a permission the request needs. For
gh,gh auth refresh -s repo,workflow; for the fallback, reconnect and approve. - Repository not visible: the token works, but GitHub will not show it this
repository. That usually means the organization enforces SAML SSO and the
token has not been authorized for it. New Chat shows a note on that repository
instead of an empty pull request list. Check
gh repo view <owner>/<name>in a terminal, then follow the link in the note when GitHub sends one, or use a classic token for an SSO organization. Local branches keep listing while this is unresolved. - Network: Rennet could not reach
github.com. This is never reported as a bad token, because an unreachable GitHub says nothing about the token. Check your connection and retry.