> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tembo.io/llms.txt
> Use this file to discover all available pages before exploring further.

# GitHub

> Create the GitHub App for Tembo on Kubernetes, with its credentials in a Kubernetes Secret.

Tembo on Kubernetes connects to GitHub through a GitHub App that you create for your install. GitHub sends users back to your install's URLs, so each install needs its own app.

Set it up before you [deploy](https://docs.tembo.io/features/self-hosted/kubernetes/deploy.md), so Tembo starts with GitHub configured. You create the app, keep its credentials in a Kubernetes Secret, and the chart reads the Secret through `github.existingSecret`. The credentials stay out of your Helm values and your deploy pipeline. If Tembo is already installed, the same steps apply, with an upgrade at the end.

You need:

* Your Tembo hostname, the `ingress.host` you deploy with (e.g. `tembo.example.com`).
* `kubectl` access to the namespace you install Tembo in. The examples use release `tembo` in namespace `tembo`.
* To create the app under a GitHub organization: an owner or GitHub App manager of that organization.

***

## Step 1: Create the GitHub App

Open **New GitHub App**: `https://github.com/organizations/<your-org>/settings/apps/new` for an organization, or **GitHub > Settings > Developer settings > GitHub Apps > New GitHub App** for your account. Fill in:

| Setting | Value |
| - | - |
| **GitHub App name** | Any name, e.g. `Tembo (tembo.example.com)` |
| **Homepage URL** | `https://<your-host>` |
| **Callback URL** | `https://<your-host>/api/oauth/github/callback` |
| **Request user authorization (OAuth) during installation** | Checked |
| **Webhook URL** | `https://<your-host>/api/webhook/github` |
| **Webhook secret** | A random string, e.g. from `openssl rand -hex 32`. Keep it for Step 3 |
| **Permissions** and **events** | As listed in [Permissions](https://docs.tembo.io/features/self-hosted/integrations/github.md#permissions) and [Subscribe to events](https://docs.tembo.io/features/self-hosted/integrations/github.md#subscribe-to-events) |

If GitHub can't reach the webhook URL, for example behind an internal load balancer, uncheck **Active** under **Webhook**. Comments that mention Tembo, issue and pull request triggers, and pull request status updates then don't work.

Then click **Create GitHub App**. [Create a GitHub App](https://docs.tembo.io/features/self-hosted/integrations/github.md#step-1-create-a-github-app) describes each setting.

> [!TIP]
>
> If Tembo is already installed without an app, `helm get notes tembo -n tembo` links to this form with your URLs, permissions and events filled in. Set `github.organization` in your values to have it link to an organization's form. Use the webhook secret the chart generated rather than your own, and leave `webhookSecret` out of the Secret in Step 3:
>
> ```bash theme={null}
> kubectl -n tembo get secret tembo-generated -o jsonpath='{.data.github\.webhookSecret}' | base64 -d
> ```

***

## Step 2: Generate a client secret and a private key

On the app's settings page:

1. Under **Client secrets**, click **Generate a new client secret** and copy it. GitHub shows it only once.
2. Under **Private keys**, click **Generate a private key**. GitHub downloads a `.pem` file.

Also note the **App ID**, the **Client ID**, and the app's slug, from its URL `https://github.com/apps/<app slug>`.

***

## Step 3: Store the credentials in a Secret

Create the namespace if it doesn't exist yet, then the Secret. `clientUserEmail` is your app's bot noreply address, which uses the bot's user ID from GitHub:

```bash theme={null}
kubectl create namespace tembo --dry-run=client --output yaml | kubectl apply --filename -

APP_SLUG=<app slug>
BOT_ID=$(curl -s "https://api.github.com/users/${APP_SLUG}%5Bbot%5D" | jq -r .id)
read -s GITHUB_APP_CLIENT_SECRET
read -s GITHUB_WEBHOOK_SECRET
kubectl create secret generic tembo-github-app \
  --namespace tembo \
  --from-literal=appId=<App ID> \
  --from-literal=appName="$APP_SLUG" \
  --from-literal=clientId=<Client ID> \
  --from-literal=clientSecret="$GITHUB_APP_CLIENT_SECRET" \
  --from-literal=webhookSecret="$GITHUB_WEBHOOK_SECRET" \
  --from-literal=clientUserEmail="${BOT_ID}+${APP_SLUG}[bot]@users.noreply.github.com" \
  --from-file=privateKey=<path to the .pem file> \
  --dry-run=client --output yaml | kubectl apply --filename -
unset GITHUB_APP_CLIENT_SECRET GITHUB_WEBHOOK_SECRET
```

Replace each `<...>` with its value; in a shell, the angle brackets themselves would be read as redirects. Check that `BOT_ID` is a number: `null` means the slug is wrong.

The Secret can hold any of these keys:

| Key | Value |
| - | - |
| `appId` | The app's **App ID** |
| `appName` | The app's slug |
| `clientId` | The app's **Client ID** |
| `clientSecret` | The client secret from Step 2 |
| `privateKey` | The contents of the `.pem` file from Step 2 |
| `webhookSecret` | The webhook secret from Step 1. Leave it out to use the one the chart generates |
| `clientUserEmail` | `<bot user ID>+<app slug>[bot]@users.noreply.github.com`. Tembo's commits are attributed to it |
| `clientUserName` | Optional. Defaults to `<app slug>[bot]` |

Values in the Secret override the same keys under `github` in your Helm values.

***

## Step 4: Point the chart at the Secret

In your `values.yaml`:

```yaml theme={null}
github:
  existingSecret: tembo-github-app
```

Then [deploy](https://docs.tembo.io/features/self-hosted/kubernetes/deploy.md) with these values. The chart reads the Secret while rendering, so it must exist first. If it's missing, the install fails with `github.existingSecret: Secret tembo-github-app is missing`.

If Tembo is already installed, upgrade instead. Use `tembo-gcp.json` instead of `tembo-aws.json` on GCP:

```bash theme={null}
helm upgrade tembo oci://registry.tembo.io/tembo --version <version> \
  -n tembo -f tembo-aws.json -f values.yaml
```

Agent hosts read the GitHub settings when they start, so after an upgrade, replace the running hosts (see [Apply changes](https://docs.tembo.io/features/self-hosted/kubernetes/configuration.md#apply-changes)).

***

## Step 5: Connect GitHub

Once Tembo is deployed, connect GitHub from Tembo, not from GitHub: Tembo only accepts an installation that starts in Tembo.

1. In Tembo, go to **Settings > Integrations** and connect GitHub.
2. Choose the organization or account, and **All repositories** or specific ones, then click **Install**. GitHub then asks you to authorize the app.
3. On the page Tembo opens next, enable the repositories Tembo should work on. You can change them later in **Settings > Repositories**.

To connect a GitHub organization, you need to be one of its owners. Otherwise GitHub sends the owners an installation request instead.

To check webhooks, open the app's **Advanced > Recent deliveries** on GitHub after a matching event, such as a comment that mentions Tembo.

***

## Rotate credentials

1. Generate a new client secret or private key on the app's settings page.
2. Update the Secret with the same `kubectl create secret ... | kubectl apply` command.
3. Run `helm upgrade` again. The platform restarts with the new values.
4. Replace the running agent hosts.
5. Delete the old client secret or private key on GitHub.

***

## GitOps and `helm template`

Argo CD, Flux and other tools that render the chart with `helm template` don't give it access to your cluster, so it can't read `github.existingSecret`. A generated webhook secret would also change on every render.

Set the app's values under `github` instead, from a values file you keep encrypted, including the webhook secret you entered in GitHub:

```yaml theme={null}
github:
  appId: "<App ID>"
  appName: "<app slug>"
  clientId: "<Client ID>"
  clientSecret: "<client secret>"
  clientUserEmail: "<bot user ID>+<app slug>[bot]@users.noreply.github.com"
  webhookSecret: "<webhook secret>"
  privateKey: |
    -----BEGIN RSA PRIVATE KEY-----
    ...
    -----END RSA PRIVATE KEY-----
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.