GitHub
Verified on 25 October 2026 against the GitHub REST API, version 2022-11-28.
The GitHub connector pins your gateway to https://api.github.com and exposes a small, deliberate slice of the REST API: repository metadata, issues, pull requests, commits, and repository search. It suits an agent that triages issues, summarizes what changed this week, or drafts a pull request description, without handing it a token it could use anywhere else on GitHub.
What you need
A fine-grained personal access token. Create one at Settings → Developer settings → Personal access tokens → Fine-grained tokens → Generate new token.
- Resource owner: yourself, or the organization that owns the repositories.
- Repository access: Only select repositories, and pick just the ones the agent should reach. This is your real blast radius; the gateway can stop the agent calling anything else, but it cannot narrow a token that was issued for every repository.
- Repository permissions. Select the least that covers what you plan to enable:
| Permission | Level | Needed for |
|---|---|---|
| Metadata | Read-only | mandatory; also backs repos.read and repository search |
| Contents | Read-only | commits.list |
| Issues | Read and write | issues.list, issues.create |
| Pull requests | Read and write | pull_requests.list, pull_requests.create, pull_requests.merge |
| Administration | Read and write | repos.delete only: leave this at No access unless you genuinely want an agent able to delete a repository |
If you only ever want reads, set Issues and Pull requests to Read-only and skip Administration entirely. Give the token a short expiry; you can rotate the connection's credential later without rebuilding it.
Copy the token when GitHub shows it. GitHub will not show it again, and once it is sealed Permaura shows it to nobody either; the one way to get it back out is a vault export, which carries every credential on the gateway.
Add the connection
Open Access → Connections → Add connection, choose GitHub from the catalog, and paste the token into the credential field. It is sealed on your gateway at that moment and never displayed again. From then on the gateway injects it server-side on each approved call.
Nothing is usable yet. A connection makes actions possible, not permitted: an agent still needs a grant before it can call anything here.
What the agent can do
| Action | What it does | On by default |
|---|---|---|
repos.read | Read repository metadata | Yes |
issues.list | List issues, filtered by state and labels | Yes |
pull_requests.list | List pull requests, filtered by state | Yes |
commits.list | List commits on a repository | Yes |
search.repos | Search repositories by query | Yes |
issues.create | Open an issue | No |
pull_requests.create | Open a pull request | No |
pull_requests.merge | Merge a pull request | No, approval required |
repos.delete | Delete a repository | No, approval required |
The four writes land switched off when you connect. Switch on only the ones you want, one at a time. pull_requests.merge and repos.delete are classified critical and carry a standing approval requirement on top: even once enabled, each call stops and waits for a human to approve it before GitHub sees it. That approval can come from the console, the Permaura app or the CLI; to make it wait for a signature from your paired device, set the action to Device-signed in its policy or raise the approval floor. issues.create and pull_requests.create are classified high, so they stop the same way: once enabled, each call waits for a human approval, from the console, the app or the CLI unless you make it Device-signed.
Good to know
- Rate limits. A personal access token gets 5,000 requests per hour. Search endpoints are tighter, and GitHub applies undisclosed secondary limits on bursts and concurrency. An agent looping over
commits.listcan trip those long before the hourly budget runs out. Both surface as 403 or 429. - The API version is pinned. The connector always sends
X-GitHub-Api-Version: 2022-11-28alongsideAccept: application/vnd.github+json, so responses keep the same shape whatever GitHub makes default. That is still GitHub's default version and is supported until 10 March 2028. GitHub also publishes a newer2026-03-10; the connector stays on the older pin deliberately, because the response shapes documented here are the ones it was authored against. - OAuth works too, but only against a GitHub App. Gateway 1.1.0 and later runs the whole authorization code flow itself, sealing the tokens on your gateway and refreshing them there; you start it through the gateway's REST API (
POST /v1/connections/:id/oauth/start), because the console has no "Sign in with GitHub" button yet. Which kind of app you register decides whether it completes: a classic OAuth app issues a user token that never expires and returns no refresh token with it, and the gateway refuses to seal a credential it cannot refresh, so the authorization link works, you approve in the browser, and the callback stops with that error. A GitHub App with expiring user access tokens left enabled does return a refresh token, alongside an eight-hour user token, and it draws its access from the permissions configured on the app rather than the scopes the connector requests. The fine-grained token stays the recommendation here: it pins to named repositories with nothing to register. - Responses are not redacted. This connector declares no redaction fields, so issue and pull request bodies come back to the agent verbatim. If your private repositories carry secrets in issue text, that is worth knowing before you grant
issues.list. - Repository search sees what the token sees.
search.reposreturns public repositories plus any private ones the token was granted, so results differ between a personal token and an organization-owned one.