GitHub
Connect GitHub twice — a read token for the agents and a Contents read-and-write token for GitOps pull requests — and capture pushes and merges with a watch list or a webhook.
How-to · Updated 2026-10-23 · Describes release 0.1.164
Overview
GitHub is where the Change agent reads commits and pull requests for last-change checks and where the compliance controls read branch protection and GitOps drift; the Incident agent reads it too. It is also the GitOps remediation path: an approved fix is a pull request on your repository, opened through a write-role connection, and nothing changes in the running estate until a person merges it. Pushes and merged pull requests reach the change ledger through a polled watch list, a webhook, or both.
The catalog marks this type write-capable, which is why the recommended setup is two connections: a fine-grained read token the agents investigate with, and a separate token with Contents: Read and write on the one repository used for pull requests.
Setup
Before you start
- The
datasources.managepermission; the built-in owner and operator roles carry it. - A fine-grained personal access token with read access to the intended repositories and, for fixes, a second read-and-write token (Installation).
Installation
In GitHub open Settings → Developer settings → Personal access tokens → Fine-grained tokens → Generate new token. For the read connection choose the resource owner, an expiry and only the repositories needed, with Contents: Read and Pull requests: Read; add Issues: Read only when issue context matters. For the write connection create a second token with Contents: Read and write and Pull requests: Read and write on the remediation repository; workflow-file edits also need Workflows: Write. Do not grant organisation administration. A token's repository selection, not the platform, decides what it can see.
Configuration
- Open Settings · Data in → Data sources and select Connect datasource.
- Under Type, choose GitHub. Enter a Connection name; the connected list shows it, and per-connection agent tools are named after it.
- Fill the fields:
| Field (portal label) | API key | Value |
|---|---|---|
| GitHub API base URL | base_url |
https://api.github.com, or https://<your-enterprise-host>/api/v3 |
| Access token | token |
Sent as Authorization: Bearer; stored write-only |
| Repositories the change agent watches (optional) | repos |
acme/payments, acme/infra-*: comma- or newline-separated owner/name, patterns allowed on GitHub |
- Optionally, open Optional · describe this environment and say in What should AIOps know about it? what this system is and what matters.
- For the agents' connection, choose Investigate only under Use this connection for and select Connect and verify. For the pull-request connection choose Approved changes only (separate credential) under Use this connection for, tick Allow use for approved plans when fixes may run on it, and save with Save remediation credential. A workspace owner can then record Repository ownership on it: the repository key, its base branch and the resource identities it manages, one per line. That is ownership evidence, not approval of any change.
The read connection through the API (POST /api/aiops/{tenant_id}/datasources, requires datasources.manage; the token goes in secret_values):
{
"type_key": "github",
"name": "github-read",
"description": "Platform repositories; acme/infra holds the Kubernetes manifests Argo CD applies.",
"config": {
"base_url": "https://api.github.com",
"repos": "acme/payments, acme/infra"
},
"secret_values": {
"token": "<fine-grained PAT, Contents: Read>"
},
"role": "read",
"enabled": true
}
The pull-request connection is the same body with the read-and-write token, "role": "write" and "allow_approved_execution": true.
Validation
Connect and verify, and Test on the row later, sends GET /rate_limit with the token. You should see a dialog titled <connection name> is connected with Connected — verified from the control plane, and later in the row's Last test ok · HTTP 200 /rate_limit — {"resources": …; a bad or expired token answers HTTP 401. GitHub serves that endpoint without authentication too, so a green result does not prove private-repository access: open one intended repository through the agent, or select Audit perms, before relying on it. A write connection saves without a probe; its token is exercised by the first approved pull request.
If something fails
The dialog shows Needs a fix, what to fix and the check's own detail; the row is saved either way. Select Edit, correct the field the detail names and save again, or select Retry once a cause outside the form (network, vendor-side permission) is fixed. Every verdict this connector produces, and what to do about it, is in Troubleshooting below.
Data collected
Tools the agent gets
<name>_request— the HTTP tool against the API base URL withAuthorization: Bearer <token>:method,path,query,body,content_type. Last-change checks readGET /repos/<owner>/<repo>/commits?since=…,GET /repos/<owner>/<repo>/pulls?state=closedandGET /repos/<owner>/<repo>/contents/<path>; branch protection comes fromGET /repos/<owner>/<repo>/branches/<branch>/protection.
Only a read-role connection renders tools; the write-role connection is invisible to every agent. Responses are capped at 20,000 characters per call.
Read surface
GET and HEAD run freely. A POST /graphql is classified from its body: a document with exactly one query operation runs, a mutation, a subscription, a batch or an unreadable document is refused. Every other POST, PUT, PATCH and DELETE — creating issues, comments, branches or files — is refused in an investigation, never offered for approval: Investigation connections are read-only. This operation was not executed; prepare an incident change using a write connection and obtain approval. The full rule table is under The read/write gate in detail in Connections and remediation access.
Changes captured
Two ways in, complements rather than alternatives:
- Watch list. The Repositories field names what the change agent polls for commits:
owner/name, a pasted browser or clone address (https://github.com/acme/payments.gitbecomesacme/payments), and on GitHub patterns such asacme/platform-*. Twenty-five repositories per connection are polled each tick; the rest are reported, never silently dropped. Only enabled read-role connections are polled, and an empty field is a real answer: that connection watches nothing. - Webhook. In the repository open Settings → Webhooks → Add webhook, set the payload URL to
https://<your-host>/webhook/github/<workspace-slug>/<webhook-token>, the content type toapplication/json, and under Let me select individual events choose Push and Pull requests. Only a merged pull request is recorded; one closed without merging changed nothing. A webhook arrives at once, the watch list minutes to hours later, and a commit seen twice is folded into one change record. The payload fields and response counters are in the webhook reference.
Pull requests as fixes
A gitops_pr route on the write connection turns an approved change into a branch and a pull request. Its parameters: repo (owner/name), the file as path or a path_template, base_branch (default main), branch (default aiops/remediation-<12 characters of the incident id>), and pr_title_template (default AIOps remediation: <incident title or path>); the content is either a whole file or a find-and-replace edit the agent proposed, and a redacted source is refused (gitops_pr: redacted content is not executable; obtain an exact fresh source). The pull request body says what it is and that no live infrastructure was touched; the platform watches for its merge and validates after it. How approvals, tiers and certification apply is in Set up write connections.
Troubleshooting
| What you see | Cause | What to do |
|---|---|---|
failed · HTTP 401 /rate_limit |
A revoked, expired or mistyped token. | Generate a new fine-grained token and rotate it on Edit. |
Test is green, but a repository read answers HTTP 404 |
The token's repository selection does not include it; GitHub answers 404, not 403, for a repository the token cannot see. | Edit the token's repository access. |
A pull request fails with gitops_pr: <step> failed: HTTP 403 … |
The write token lacks Contents: Read and write, or the branch is protected against it. | Fix the token's permissions on the remediation repository. |
gitops_pr: route params missing 'repo' or gitops_pr: missing 'path'/'path_template' |
The route is incomplete. | Fill repo and path on the route. |
gitops_pr: the edit anchor is not in <path> — … |
The file changed since the agent read it. | Re-run the analysis so the edit matches the current file. |
A POST /graphql with a mutation, or a PUT /repos/…/contents/…, answers Investigation connections are read-only. |
The write gate. | Expected; a fix is a pull request through the write connection. |
| The Changes page shows a repository as last poll failed with an HTTP status | The read token cannot see that repository, or the name is wrong. | Fix the name in Repositories, or the token's access. |
| A repository on a write connection shows as named but not polled | Only read-role connections are polled. | List it on the read connection. |
| Pushes arrive by webhook but merges do not | The webhook does not subscribe to Pull requests. | Add the event; a pull request closed without merging is never recorded. |
The generic verdict strings are explained in Test a connection and read the failure. Every connection status word is in the status and error reference.
Next steps
- Select Discover this connection in the success dialog to find the services and dependencies behind it: Launch a scan.
- See which pushes and merges the change agent records: Changes captured.
- Let approved fixes land as pull requests: Pull requests as fixes.
- See what else each agent needs in Choose your connection.