Automates the installation of GitHub Apps to organizations within a GitHub Enterprise. This workflow uses an "installer app" with enterprise-level permissions to install target apps to specified organizations.
Based on GitHub's guide for automating app installations.
- GitHub Enterprise Cloud
- Enterprise owner or admin permissions
The installer app is an enterprise-owned GitHub App that has permission to install other apps to organizations.
- Go to your enterprise settings:
https://github.com/enterprises/YOUR-ENTERPRISE/settings/apps - Click New GitHub App
- Configure the app:
- GitHub App name:
YOUR-ENTERPRISE-installer(or similar) - Homepage URL: Your enterprise URL or this repository URL
- Webhook: Uncheck "Active" (not needed)
- GitHub App name:
- Set permissions:
- Under Organization permissions, set Enterprise organization installations to Read and write
- Under Where can this GitHub App be installed?, select Only on this account
- Click Create GitHub App
- On the app's settings page, scroll to Private keys
- Click Generate a private key
- Save the downloaded
.pemfile securely
- On the app's settings page, click Install App in the sidebar
- Select your enterprise account
- Click Install
- On the app's settings page, copy the Client ID (starts with
Iv)
Go to this repository's Settings > Secrets and variables > Actions
| Name | Value |
|---|---|
INSTALLER_APP_PRIVATE_KEY |
Contents of the .pem file (include the BEGIN/END lines) |
| Name | Value |
|---|---|
ENTERPRISE_SLUG |
Your enterprise slug (from URL: github.com/enterprises/YOUR-SLUG) |
INSTALLER_APP_CLIENT_ID |
The Client ID from step 4 |
Note
Requires GHES 3.19 or later. See the GHES 3.19 release notes.
- The StepSecurity apps must already be registered on your GHES instance and
installed on at least in one org before running this tool, that's how the
apps get their client IDs (
REGULAR_APP_CLIENT_ID/ADVANCED_APP_CLIENT_ID). Set this up first via the GHES admin console guide, then use this tool to roll the install out to the rest of your organizations. - A self-hosted (or GHES-hosted) runner inside your network so the workflow can reach the GHES API.
- GitHub App name:
YOUR-ENTERPRISE-installer(or similar) - Homepage URL: Your enterprise URL or this repository URL
- Webhook: Uncheck "Active" (not needed)
- Set permissions:
- Under Enterprise permissions, set Enterprise organization installations to Read and write
- Under Where can this GitHub App be installed?, select Only on this account
- On the app's settings page, scroll to Private keys
- Click Generate a private key
- Save the downloaded
.pemfile securely
- On the app's settings page, click Install App in the sidebar
- Select your enterprise account
- Click Install
- Installer app: on the app's settings page, copy the Client ID (starts with
Iv) - Target apps: get the Client IDs of the StepSecurity apps you already registered/installed on this GHES instance, see the GHES admin console guide
- Push this repo to a repository hosted on your GHES instance
- Ensure a self-hosted runner is available (adjust
runs-onin install-app-ghes.yml if you use a specific label)
Go to this repository's Settings > Secrets and variables > Actions (on the GHES repo)
| Name | Value |
|---|---|
INSTALLER_APP_PRIVATE_KEY |
Contents of the .pem file (include the BEGIN/END lines) |
| Name | Value |
|---|---|
ENTERPRISE_SLUG |
Your enterprise slug |
INSTALLER_APP_CLIENT_ID |
The installer app Client ID |
REGULAR_APP_CLIENT_ID |
Regular app Client ID (as registered on this instance) |
ADVANCED_APP_CLIENT_ID |
Advanced app Client ID (as registered on this instance) |
Edit organizations.txt and add one organization name per line:
my-org-1
my-org-2
my-org-3
Lines starting with # are treated as comments.
The workflow runs automatically when:
organizations.txtis modified (push to main)- Daily at midnight UTC (scheduled)
To run manually:
- Go to Actions > Install GitHub App to Organizations
- Click Run workflow
- Optionally enable Dry run to check status without installing
This workflow installs the following apps (hardcoded):
| App | Client ID |
|---|---|
| StepSecurity Actions Security App | Iv1.ad96d1f00234487b |
| StepSecurity App (Advanced App) | Iv23liR5Z8C22IM5THOA |
To modify the target apps, edit the APPS array in .github/workflows/install-app.yml.
The workflow reports:
- Newly installed: Apps that were installed during this run
- Already installed: Apps that were already present
- Failed: Apps that failed to install (check logs for details)
When the workflow runs, you'll see output like this:
=== Processing organizations ===
Apps to install (in order):
1. StepSecurity Actions Security App
2. StepSecurity App (Advanced App)
==========================================
Processing organization: step-integration-tests
==========================================
--- [1/2] StepSecurity Actions Security App (Iv1.ad96d1f00234487b) ---
Already installed (installation ID: 72605456)
Waiting 5 seconds before next app...
--- [2/2] StepSecurity App (Advanced App) (Iv23liR5Z8C22IM5THOA) ---
Already installed (installation ID: 72605887)
==========================================
Processing organization: step-dev-org-1
==========================================
--- [1/2] StepSecurity Actions Security App (Iv1.ad96d1f00234487b) ---
Already installed (installation ID: 97537007)
Waiting 5 seconds before next app...
--- [2/2] StepSecurity App (Advanced App) (Iv23liR5Z8C22IM5THOA) ---
Already installed (installation ID: 97537005)
==========================================
Processing organization: step-dev-org-2
==========================================
--- [1/2] StepSecurity Actions Security App (Iv1.ad96d1f00234487b) ---
Successfully installed
Waiting 5 seconds before next app...
--- [2/2] StepSecurity App (Advanced App) (Iv23liR5Z8C22IM5THOA) ---
Successfully installed
=== Summary ===
Newly installed: 2
Already installed: 4
Failed: 0
The private key is not configured correctly. Ensure:
- The secret
INSTALLER_APP_PRIVATE_KEYexists - The full PEM content is included (with
-----BEGIN RSA PRIVATE KEY-----headers)
The installer app is not installed on your enterprise. Go to the app's settings and install it on your enterprise account.
This can happen if the install API is idempotent. The workflow now checks existing installations before attempting to install.