Repair the Rowbutt GitHub credential
Check, resync, rotate and replace the GitHub App credential that Rowbutt's sandboxes push with.
This runbook repairs the GitHub credential of Rowbutt. mate, the process that runs Rowbutt, makes a GitHub token for each turn (one prompt and the agent's answer) from the private key of the clanky-bot GitHub App. Use it when MateGitHubCredentialBroken or MateGitHubTokenMintFailing fires, or when a sandbox cannot push.
warning
This runbook changes the GitHub App, the 1Password item and an ExternalSecret annotation by hand. It is an exception to the GitOps rule because git does not hold the private key or the App settings. Do not edit the mate-github-app Secret. External Secrets overwrites it within the hour.
Before you start#
- Get
kubectlaccess to offsite (Get cluster admin access). - Get write access to the
homelabvault in 1Password. - Get admin access to the GitHub App.
- Install
gh.
Check the credential#
mate tests the key at start and every 15 minutes.
Read the last GitHub lines of the mate log.
kubectl --context offsite -n mate logs deploy/mate | grep -i -E 'github|credentials' | tail -5Result: The log shows
github app ready, with the loginclanky-bot[bot]and a futureexpiresAt.Read the ExternalSecret status.
kubectl --context offsite -n mate get externalsecret mate-github-appResult: The command prints
SecretSyncedandTrue.
Resync the Secret#
Do this procedure to apply a 1Password change now. Reloader, a controller that restarts pods when their Secret changes, restarts mate after the sync.
Annotate the ExternalSecret.
kubectl --context offsite -n mate annotate externalsecret mate-github-app \ force-sync="$(date +%s)" --overwriteRead the ExternalSecret.
kubectl --context offsite -n mate get externalsecret mate-github-appResult:
LAST SYNCshows a few seconds, andSTATUSisSecretSynced.If the Secret changed, wait until Reloader restarts mate.
kubectl --context offsite -n mate rollout status deploy/mateResult: The command prints
deployment "mate" successfully rolled out.Do step 1 of Check the credential.
Rotate the private key#
In GitHub, open Settings > Developer settings > GitHub Apps >
clanky-bot.Select Generate a private key.
Result: The browser downloads a
.pemfile. The old key stays valid.
warning
Do not put the key or its base64 in git or in a chat.
Encode the key as one line of base64.
base64 -w0 <key>.pem > <key>.b64
caution
If the field pem (base64) holds PEM text or wrapped base64, mate cannot parse the key.
- Put the content of
<key>.b64in the fieldpem (base64)of the itemclanky-bot github appin thehomelabvault. - Do Resync the Secret.
caution
If you delete the old key before step 5 passes, mate cannot make tokens.
- In the App settings, delete the old private key.
- Delete
<key>.pemand<key>.b64.
Replace the App#
If the clanky-bot App is deleted or unusable, do this procedure. <slug> is the name of the new App in its URL.
In Settings > Developer settings > GitHub Apps, create an App with no webhook.
Give it these repository permissions: Contents read and write, Pull requests read and write, Actions read-only.
Record the App ID.
Install the App on the
jonpulsiferaccount, for theinfrarepository only.Get the user ID of the App's bot.
gh api 'users/<slug>[bot]' --jq .idResult: The command prints
<bot-id>.Open a pull request that sets these values:
MATE_GITHUB_APP_IDinclusters/offsite/apps/mate/deployment.yaml: the App IDGIT_USERinapps/mate/src/sandboxes.ts:<slug>[bot]GIT_EMAILin the same file:<bot-id>+<slug>[bot]@users.noreply.github.comclanky-bot[bot]inatlantis_usersinclusters/offsite/apps/atlantis/policies/only-me.rego:<slug>[bot]clanky-bot[bot]inatlantis_appliersinclusters/offsite/apps/atlantis/policies/appliers.rego:<slug>[bot]
caution
mate cannot make tokens from step 7 until it restarts with the new App ID.
In the new App settings, do steps 2 to 4 of Rotate the private key.
Merge the pull request.
Wait until the CD pull request for the
mateimage digest merges.-
Result: The log shows
github app ready, with the login<slug>[bot]. Delete the old App.
Delete
<key>.pemand<key>.b64.
If something goes wrong#
| Symptom | Cause | Action |
|---|---|---|
The log shows private key does not parse. | pem (base64) holds PEM text or wrapped base64. | Do Rotate the private key. |
The log shows could not be opened. | The Secret does not exist. | Read the ExternalSecret events with kubectl describe. |
The status is SecretSyncedError. | pem (base64) is missing. 1Password Connect returns no value for the password field of a Password item. | Put the key in pem (base64). |
The log shows github said 401. | GitHub refuses the key or the App ID. | Rotate the key. Make sure that MATE_GITHUB_APP_ID is correct. |
The log shows find installation: github said 404. | The App is not installed on infra. | In the App settings, install it on jonpulsifer/infra only. mate finds it within 15 minutes. |
gh prints no token in, or git prints could not read Username. | The turn has no token. | Read the could not mint and could not stamp lines in the mate log. |
The log shows could not mint. | mate could not make the token. | Do Check the credential. |
The log shows could not stamp. | The mate-hands link could not write the turn's files into the sandbox: the link dropped, or pods/exec into the sandbox failed. | Read the error field of the line. |
| The push does not end. | The sandbox egress policy blocks the host. | Read clusters/offsite/apps/mate/sandbox-network-policy.yaml. |
Related#
Linked from 3
- RowbuttA chat bot, code name mate, that answers the owner in Discord and Slack threads with a coding agent whose tools run in a sandbox on the offsite cluster.
- RunbooksStep-by-step procedures for the hosts, clusters, network, secrets and apps, grouped by area.
- Rotate the Rowbutt Slack tokenReplace the Slack App-Level Token that Rowbutt's Socket Mode connection uses, and revoke the tokens of clients that share its events.