GitHub App Setup
Konstruct uses a GitHub App to manage GitOps repositories, automate infrastructure delivery, and perform secure Git operations (clone, push, pull) across your workload clusters.
Each self-hosted Konstruct instance requires its own dedicated GitHub App. This guide walks you through creating the app on GitHub and collecting the credentials needed to configure the Konstruct API.
Prerequisites
- A GitHub account with permission to create GitHub Apps in your organization or personal account
- Your Konstruct instance URL (e.g.,
https://konstruct.example.com) - Access to your Vault instance where the Konstruct API secret is stored
Summary of Steps
- Create the GitHub App
- Configure app settings
- Set repository and organization permissions
- Configure installation scope
- Collect credentials for the Konstruct API
- Configure the Konstruct API
1. Create the GitHub App
-
Go to github.com/settings/apps/new to create the app under your personal account, or navigate to your organization's settings: Organization Settings → Developer Settings → GitHub Apps → New GitHub App.
-
Fill in the App name field. Use a unique, descriptive name that identifies your Konstruct instance, for example:
Konstruct(for a single shared instance)Konstruct-Production(for a named instance)Konstruct-AcmeCorp(for a customer-specific install)
-
In the Description field, enter:
Konstruct connects to your GitHub organizations to manage GitOps repositories
and automate infrastructure delivery. It creates and manages gitops repos,
reads repository metadata, and generates short-lived installation tokens for
secure Git operations across your workload clusters. -
Set the Homepage URL to your Konstruct instance URL, for example:
https://konstruct.example.com
2. Configure App Settings
Callback URL
Set the Callback URL to your Konstruct instance domain with the OAuth callback path:
https://<YOUR_DOMAIN>/api/v1/github-app/callback
Example:
https://konstruct.example.com/api/v1/github-app/callback
The callback URL domain must exactly match your Konstruct instance domain. A mismatch will cause OAuth authentication failures when users install or authorize the app.
Post Installation Setup
- Setup URL (optional): Leave blank.
- Redirect on update: Leave unchecked.
User Authorization
| Setting | Value |
|---|---|
| Expire user authorization tokens | Enabled |
| Request user authorization (OAuth) during installation | Enabled |
| Enable Device Flow | Disabled |
Enabling token expiration is the recommended security posture. Access tokens expire after 8 hours and are refreshed automatically. Users will not be prompted to re-authorize unless their refresh token also expires.
Webhooks
- Active: Uncheck this checkbox. Webhooks are not required by Konstruct at this time.
3. Set Permissions
Scroll to the Permissions section and configure the following access levels.
Repository Permissions
| Permission | Access Level | Why Konstruct Needs It |
|---|---|---|
| Actions | Read & Write | Manage GitHub Actions workflows used in GitOps CI/CD pipelines |
| Administration | Read & Write | Manage repository settings and branch protection rules |
| Contents | Read & Write | Clone repositories, read files, commit, and push to GitOps repos |
| Metadata | Read-only | Read repository metadata (always granted by GitHub, cannot be deselected) |
| Pull requests | Read & Write | Create and manage pull requests for GitOps workflows |
| Secrets | Read & Write | Store workflow trigger tokens as GitHub Actions secrets for CI/CD pipelines |
| Workflows | Read & Write | Manage and trigger GitHub Actions workflow files |
Organization Permissions
| Permission | Access Level | Why Konstruct Needs It |
|---|---|---|
| Administration | Read-only | Read organization settings and configuration |
| Members | Read-only | List organization members and teams for access control |
Account Permissions
| Permission | Access Level | Why Konstruct Needs It |
|---|---|---|
| Email addresses | Read-only | Identify the authenticated user during OAuth login |
Do not grant permissions beyond those listed above. Konstruct does not require write access to organization settings or webhooks.
4. Configure Installation Scope
Under Where can this GitHub App be installed?, choose the appropriate option for your deployment:
| Option | When to Use |
|---|---|
| Any account | Public or shared Konstruct instances where multiple GitHub organizations need to install the app |
| Only on this account | Private or organization-internal deployments where a single org owns and uses the app |
Click Create GitHub App to finalize creation.
5. Collect Credentials
After creation, GitHub redirects you to the app's settings page. Collect each of the following values before leaving this page. You will need them to configure the Konstruct API.
App ID
On the app settings page under About, locate the App ID field (a numeric value).
| Env Variable | Where to Find |
|---|---|
GITHUB_APP_ID | App settings → General → About → App ID |
Client ID
Also under About, locate the Client ID field (a string starting with Iv1.).
| Env Variable | Where to Find |
|---|---|
GITHUB_APP_CLIENT_ID | App settings → General → About → Client ID |
Client Secret
Scroll to Client secrets and click Generate a new client secret.
| Env Variable | Where to Find |
|---|---|
GITHUB_APP_CLIENT_SECRET | App settings → General → Client secrets → Generate a new client secret |
The client secret is shown only once. Copy and store it immediately in a secure location. If you navigate away without saving it, you must generate a new secret.
Private Key
Scroll to Private keys and click Generate a private key. GitHub downloads a .pem file.
| Env Variable | Where to Find |
|---|---|
GITHUB_APP_PRIVATE_KEY | App settings → General → Private keys → Generate a private key |
The value of GITHUB_APP_PRIVATE_KEY is the entire contents of the downloaded .pem file, including the header and footer lines:
-----BEGIN RSA PRIVATE KEY-----
...key contents...
-----END RSA PRIVATE KEY-----
GITHUB_APP_WEBHOOK_SECRET is not required. Leave it empty.
App Name (Slug)
The app slug is the URL-friendly version of your app name. You can find it in the browser address bar when viewing the app settings page:
https://github.com/settings/apps/<app-slug>
| Env Variable | Where to Find |
|---|---|
GITHUB_APP_NAME | The URL slug from the app settings URL (lowercase, hyphen-separated) |
Example: If your app is named Konstruct-Production, the slug will be konstruct-production.
Credentials Summary
| GitHub App Setting | Env Variable | Example Value |
|---|---|---|
| App ID | GITHUB_APP_ID | 12345678 |
| Client ID | GITHUB_APP_CLIENT_ID | Iv1.a1b2c3d4e5f6a7b8 |
| Client Secret | GITHUB_APP_CLIENT_SECRET | a1b2c3d4e5f6... |
| Private Key | GITHUB_APP_PRIVATE_KEY | Full PEM file contents |
| Webhook Secret | GITHUB_APP_WEBHOOK_SECRET | (leave empty) |
| App Name (slug) | GITHUB_APP_NAME | konstruct-production |
6. Configure the Konstruct API
These values are stored in Vault and injected into the Konstruct API secret. Add the following keys to your Vault instance under the Konstruct secrets path:
vault kv put secret/konstruct/konstruct-api \
GITHUB_APP_ID="12345678" \
GITHUB_APP_CLIENT_ID="Iv1.a1b2c3d4e5f6a7b8" \
GITHUB_APP_CLIENT_SECRET="your-client-secret" \
GITHUB_APP_NAME="konstruct-production" \
GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA...
...rest of key...
-----END RSA PRIVATE KEY-----"
The private key is sensitive material. Ensure your Vault policy restricts read access to only the Konstruct API and operator service accounts.
Verification
After configuring the environment variables and redeploying the Konstruct API:
- Open your Konstruct instance URL in a browser.
- Navigate to an organization and attempt to register a GitOps repository.
- Confirm that the GitHub App installation flow launches and completes without error.
- Verify that the GitOps repository is created in the target GitHub organization.
Troubleshooting
OAuth callback fails or redirects to an error page
Symptom: After authorizing the GitHub App, the browser is redirected to an error page or the callback URL returns a 404 or 400.
Check:
- The Callback URL in the GitHub App settings exactly matches your Konstruct domain, including the path
/api/v1/github-app/callback. - There are no trailing slashes or mismatched
http/httpsschemes. - The Konstruct API is running and accessible at that domain.
"Invalid client" or authentication error during installation
Symptom: GitHub returns an invalid_client error or similar OAuth error.
Check:
GITHUB_APP_CLIENT_IDandGITHUB_APP_CLIENT_SECRETare set correctly.- The client secret has not expired. Client secrets do not have a built-in expiry, but a new secret is required if the old one was regenerated.
- The environment variables are loaded by the running API process (restart the pod if needed).
Git operations fail with authentication errors
Symptom: Clone, push, or pull operations fail with authentication failed or permission denied errors.
Check:
GITHUB_APP_PRIVATE_KEYcontains the complete PEM contents, including-----BEGIN RSA PRIVATE KEY-----and-----END RSA PRIVATE KEY-----lines.- No extra whitespace or newline characters were stripped during secret creation.
GITHUB_APP_IDmatches the numeric ID of the correct GitHub App.- The GitHub App has been installed on the target organization (not just created).
"App not installed on this organization" error
Symptom: Konstruct reports that the GitHub App is not installed when attempting to register a GitOps repository.
Resolution: The GitHub App must be explicitly installed on the target GitHub organization. Go to:
https://github.com/apps/<app-slug>/installations/new
Select the organization and grant the requested permissions.
Application reconciliation fails with "Resource not accessible by integration"
Symptom: The application operator logs show an error like:
failed to add workflow token secret: failed to get public key:
GET https://api.github.com/repos/<org>/<repo>/actions/secrets/public-key:
403 Resource not accessible by integration []
Cause: The GitHub App is missing the Secrets repository permission. Konstruct needs this permission to store the WORKFLOW_TRIGGER_TOKEN as a GitHub Actions secret on the application repository, which CI/CD pipelines use to trigger deployments.
The token used for this API call comes from the GitAccount CR (not the platform-level konstruct-git-config secret). The GitAccount resolves its credentials based on its authType:
github_app: generates an installation token from the GitHub App referenced inspec.secretRef- PAT: uses the decrypted personal access token from
spec.accessToken
Resolution:
-
Go to your GitHub App settings: GitHub → Settings → Developer settings → GitHub Apps → Your App → Permissions & events.
-
Under Repository permissions, set Secrets to Read and write.
-
Save the changes. GitHub will prompt the organization owner to accept the updated permissions.
-
Go to each organization where the app is installed and accept the updated permissions at:
https://github.com/organizations/<ORG_NAME>/settings/installations -
After the updated permissions are accepted, retry the application reconciliation or wait for the next reconcile cycle.
Updating the GitHub App permissions does not take effect immediately. Each organization owner must individually accept the new permissions. The error will persist until the permission is accepted for the specific organization referenced by the GitAccount. Check for a pending review banner on the organization's GitHub App installation page.
Private key format error
Symptom: The API logs show a PEM parsing error or invalid private key message.
Check:
- The entire
.pemfile contents are present in Vault, not just the key body. - Newlines are preserved. Verify the value in Vault starts with
-----BEGIN RSA PRIVATE KEY-----.
What's Next?
After setting up the GitHub App:
- Connect a GitHub organization for your first organization
- Configure cloud accounts for cluster provisioning
- Create your first cluster