SOP Owner:
LIHG Administration / UHD Administration
System: Unified Help Desk (UHD)
Purpose: Enterprise GitHub integration
Authentication Standard: Organization-owned GitHub App
Applies To: Production integrations between UHD and LIHG GitHub
repositories
This SOP establishes
the standard method for connecting UHD to GitHub.
UHD should authenticate
to GitHub through an organization-owned GitHub App, rather than through
a personal access token belonging to an individual developer or administrator.
GitHub Apps can operate
independently of individual users, use narrowly scoped permissions,
authenticate as an installation, and use centralized webhooks.
The GitHub App should
be:
Owned by: LIHG
GitHub organization
Used by: UHD
Installed on: LIHG GitHub organization
Repository scope: All LIHG repositories required by UHD
Authentication: GitHub App installation authentication
Webhook security: Dedicated high-entropy secret
Secret storage: Production environment / approved secret manager
Recommended
GitHub App name:
LIHG
UHD Enterprise Integration
GitHub App
names must be unique on GitHub and currently cannot exceed 34 characters.
Recommended
description:
Enterprise
GitHub integration service for Unified Help Desk (UHD) across LIHG repositories
and platforms.
Sign
into GitHub using an account with appropriate ownership/administrative
authority over the LIHG GitHub organization.
Navigate
to:
Profile
Picture → Your organizations
Locate
the LIHG organization.
Select:
Settings
Then:
Developer
settings → GitHub Apps → New GitHub App
GitHub
allows an organization owner, or someone granted appropriate GitHub App
management authority, to register an app under the organization.
Enter:
LIHG UHD Enterprise
Integration
Enter:
Enterprise GitHub
integration service for Unified Help Desk (UHD) across LIHG repositories and
platforms.
Enter the primary production UHD URL.
Example:
https://YOUR-UHD-DOMAIN.com
Use the actual UHD production domain.
Leave blank for the initial server-to-server
UHD integration.
UHD does not currently need GitHub users to
authorize the application individually.
GitHub states that the callback URL is not
necessary when an app does not need to generate user access tokens.
Leave:
OFF
Leave:
OFF
May be left blank unless UHD later develops an
installation/setup page.
Find the:
Webhook
section.
Set:
Active: ON
GitHub Apps
have centralized webhook functionality and can receive events for repositories
accessible to the installation.
For
the existing UHD EOD Reports plugin, the developer identified the webhook
endpoint as:
eod_reports/github/webhook
The
full production webhook URL should therefore resemble:
https://YOUR-UHD-DOMAIN.com/eod_reports/github/webhook
The
developer must confirm the exact production URL before the GitHub App is
activated.
GitHub
requires an HTTPS-accessible webhook URL where it can send event payloads.
Do
not use:
·
a GitHub password;
·
a Personal Access Token;
·
the GitHub App private key;
·
the Client ID;
·
the App ID.
The
webhook secret is a separate random security credential.
On
Windows, open PowerShell.
Run:
$bytes = New-Object byte[] 32
[System.Security.Cryptography.RandomNumberGenerator]::Fill($bytes)
[Convert]::ToHexString($bytes).ToLower()
This
generates a 64-character hexadecimal secret based on 32 random bytes.
Copy
the generated value.
Example
format only:
8e61a4...64-random-hex-characters...
Never
reuse the example.
GitHub
recommends using a high-entropy random value for the GitHub App webhook secret.
On
the GitHub App creation page locate:
Webhook
secret
Paste
the newly generated secret.
Do
not publish or commit this value.
The
exact same secret must later be installed in the UHD production environment.
UHD’s
webhook handler should verify GitHub’s:
X-Hub-Signature-256
signature
before accepting the request. GitHub recommends HMAC-SHA256 validation using
this header.
Set:
SSL
verification: Enable SSL verification
Do not disable
SSL verification in production.
GitHub
strongly recommends SSL verification for GitHub App webhooks.
For
the current UHD EOD evidence integration, start with least-privilege read
access.
Under:
Repository
permissions
configure:
Read-only
Purpose:
Allows UHD to retrieve repository content-related
information needed for branches and commits.
Read-only
Purpose:
Allows UHD to retrieve pull-request
information.
Read-only
GitHub provides repository metadata access as
part of GitHub App repository access.
Do not grant write access merely because UHD has
access to all repositories.
Repository coverage and permission level are two
different controls.
GitHub App permissions determine which APIs and
resources an installation can access, and GitHub recommends using the minimum
permissions required.
For
the current EOD evidence feature, do not grant write access for:
·
Contents
·
Pull requests
·
Actions
·
Workflows
·
Administration
·
Deployments
·
Secrets
·
Environments
·
Issues
unless
a future UHD function specifically requires the capability and the permission
is separately approved.
Future
UHD capabilities may require additional permissions, but they should be added
individually as needed.
Changing
GitHub App permissions later can require approval of the updated permissions
for installed applications.
Under:
Subscribe
to events
enable:
Required for Git push/commit activity.
Required for pull-request activity.
The current developer handover states that
the UHD EOD webhook handler already supports:
ping
push
pull_request
GitHub only displays webhook event options
supported by the permissions assigned to the app.
Under:
Where
can this GitHub App be installed?
Select:
Only
on this account
This
keeps the application private to the organization that owns it instead of
making it installable by arbitrary outside GitHub accounts.
Review
all settings.
Select:
Create
GitHub App
The
GitHub App now exists, but creation alone does not give UHD access to
organization repositories.
The
application must next be installed on the LIHG organization.
Open
the newly created GitHub App’s settings.
Locate:
App
ID
Record
it.
Important:
App
ID and Client ID are not the same thing.
For
server-to-server installation authentication, the developer will primarily need
the App ID, installation information, and private key. GitHub
specifically distinguishes App ID from Client ID.
Recommended
future UHD environment variable:
UHD_GITHUB_APP_ID=<APP_ID>
In
the GitHub App settings, scroll to:
Private
keys
Select:
Generate
a private key
GitHub
will generate and download a:
.pem
private-key
file.
GitHub
stores only the public portion after generation, so the downloaded private key
must be securely retained.
The
filename may resemble:
lihg-uhd-enterprise-integration.2026-08-10.private-key.pem
The
private key is one of the most sensitive UHD integration credentials.
Do NOT:
·
email it casually;
·
commit it to GitHub;
·
store it in a README;
·
place it in an EOD report;
·
include it in screenshots;
·
place it in a public/shared folder;
·
paste its contents into source code.
GitHub
explicitly recommends protecting private keys and states that they should not
be hard-coded, even when the repository itself is private. GitHub identifies a
key vault as stronger protection than a plain environment variable.
Preferred
long-term storage:
Azure
Key Vault or equivalent enterprise secret manager
Acceptable
transitional storage:
Protected
server credential directory accessible only to the UHD application account.
Return
to:
Organization
Settings → Developer settings → GitHub Apps
Locate:
LIHG
UHD Enterprise Integration
Select:
Edit
Then:
Install
App
Find
the LIHG organization.
Select:
Install
GitHub
allows organization-owned apps to be installed directly on the organization.
When
GitHub asks:
Repository
access
Select:
This is the
appropriate selection because UHD is the enterprise integration platform rather
than a single-project application.
GitHub
provides the installation choices:
All
repositories
or
Only select
repositories.
The security
boundary should primarily come from the GitHub App’s functional permissions.
For example:
All
repositories + Contents Read-only
means UHD has
read-only Contents permission across the repositories covered by the
installation; it does not give UHD permission to modify repository contents.
The
developer needs the GitHub App’s organization installation ID for
server-to-server authentication.
Recommended
environment variable:
UHD_GITHUB_INSTALLATION_ID=<INSTALLATION_ID>
The
installation ID can be determined through GitHub’s API or installation
information. GitHub App webhook payloads also include the installation ID.
The
GitHub App should NOT use a permanent PAT.
The
flow becomes:
GitHub App ID
+
GitHub App Private Key
↓
UHD generates signed JWT
↓
GitHub verifies GitHub App
↓
UHD requests Installation Access Token
↓
GitHub provides temporary token
↓
UHD accesses authorized repositories
GitHub
installation access tokens currently expire after one hour. UHD should
generate/refresh them automatically rather than storing a permanent
installation token.
This
is an important security advantage over storing a long-lived developer PAT.
The
UHD developer should receive the following configuration information:
# UHD Enterprise GitHub App
UHD_GITHUB_APP_ID=<ACTUAL_APP_ID>
UHD_GITHUB_INSTALLATION_ID=<ACTUAL_INSTALLATION_ID>
UHD_GITHUB_PRIVATE_KEY_PATH=<SERVER_PATH_TO_SECURE_PEM_FILE>
UHD_GITHUB_WEBHOOK_SECRET=<ACTUAL_WEBHOOK_SECRET>
Depending
on the implementation, the developer may instead use a secret manager reference
rather than a filesystem path for the private key.
The private
key should preferably be installed directly into the production secret
environment by an authorized administrator, rather than being distributed
through ordinary chat or email.
The
current EOD implementation uses:
UHD_EOD_GITHUB_REPOSITORIES=
UHD_EOD_GITHUB_TOKEN=
UHD_EOD_GITHUB_WEBHOOK_SECRET=
This
was designed around a Personal Access Token.
The
permanent enterprise implementation should be revised to support something
similar to:
UHD_GITHUB_APP_ID=
UHD_GITHUB_INSTALLATION_ID=
UHD_GITHUB_PRIVATE_KEY_PATH=
UHD_GITHUB_WEBHOOK_SECRET=
The
repository allowlist may remain if UHD wants an additional application-level
filtering mechanism, but GitHub App authentication should no longer depend
on a person’s PAT.
The
developer should modify Github_service.php
so that UHD:
1.
Loads the GitHub App ID.
2.
Securely loads the GitHub App private key.
3.
Generates a signed JWT.
4.
Authenticates to the correct LIHG GitHub App
installation.
5.
Requests an installation access token.
6.
Uses that temporary installation token for
GitHub REST API calls.
7.
Automatically obtains another token when
necessary.
8.
Does not require a permanent Personal Access
Token for normal production operation.
GitHub’s
supported server-to-server GitHub App model uses installation access tokens
generated after authenticating the app.
The
GitHub App should use one centralized webhook configuration.
For the
current EOD system:
Webhook URL:
https://YOUR-UHD-DOMAIN.com/eod_reports/github/webhook
The
same webhook secret must exist on both sides:
GitHub App
Webhook Secret
│
│ Same
value
▼
UHD Production Secret
GitHub
Apps provide centralized webhook handling for resources available to their
installations.
This
eliminates the need to manually create a separate repository webhook for every
LIHG repository once UHD has transitioned properly to the GitHub App model.
The
developer must demonstrate all of the following before the GitHub integration
is considered complete:
☐
GitHub App owned by the LIHG organization
☐
GitHub App installed on the LIHG organization
☐
Repository access set appropriately
☐
Contents permission is Read-only unless separately approved
☐ Pull
requests permission is Read-only unless separately approved
☐ Push
webhook subscribed
☐ Pull
request webhook subscribed
☐
Webhook SSL verification enabled
☐
Webhook secret configured
☐ X-Hub-Signature-256
successfully validated
☐
GitHub App private key stored outside source control
☐ UHD
can generate an installation access token
☐ UHD
can retrieve repositories
☐ UHD
can retrieve branches
☐ UHD
can retrieve commits
☐ UHD
can retrieve pull requests
☐ New
push events update the UHD GitHub cache
☐ New
pull-request events update the UHD cache
☐
Existing EOD repository dropdown works
☐
Branch dropdown works
☐
Commit dropdown works
☐
Pull-request dropdown works
☐ No
GitHub PAT is required for normal production authentication
☐ No
GitHub secret or private key exists in source control
☐ A
newly created LIHG repository is tested to confirm the organization’s intended
repository-access behavior
GitHub
App private keys do not automatically expire. They must be deliberately rotated
and revoked. GitHub allows multiple private keys for an application so a
replacement can be introduced before removing the old key.
Standard
rotation procedure:
1.
Generate a new private key.
2.
Add the new key to UHD’s secure production
environment.
3.
Test GitHub authentication.
4.
Confirm UHD is operating using the new
credential.
5.
Delete/revoke the old private key from GitHub.
6.
Remove the old credential from the server or
secret manager.
7.
Record the rotation in the credential register.
Never
delete the currently functioning key before the replacement has been tested.
To
rotate the webhook secret:
1.
Generate a new cryptographically random value.
2.
Coordinate the GitHub and UHD changes.
3.
Replace the GitHub App webhook secret.
4.
Replace the corresponding UHD production secret.
5.
Send a test webhook.
6.
Confirm X-Hub-Signature-256
validation succeeds.
7.
Record the rotation date.
GitHub
recommends securing GitHub App webhooks with a high-entropy secret and
validating incoming webhook payloads.
Going
forward:
Developers
should not create the permanent UHD integration identity.
LIHG/UHD
administration creates and owns it.
Developers
implement against credentials supplied through the approved
environment/secret-management process.
The
organization retains control of:
·
GitHub App ownership
·
Repository installation
·
Permission approvals
·
Private keys
·
Webhook secrets
·
Production secret storage
·
Credential rotation
·
Credential revocation
Developers
retain responsibility for:
·
Code integration
·
Secure authentication implementation
·
Token refresh
·
Webhook validation
·
Error handling
·
Testing
·
Deployment verification
LIHG
GitHub Organization
│
│ owns
▼
LIHG
UHD Enterprise GitHub App
│
┌───────────┴───────────┐
│ │
Installation API Webhooks
│ │
Temporary
Access push / PR
Tokens │
│ │
└───────────┬───────────┘
▼
Unified Help Desk
│
┌───────────┼───────────┐
▼ ▼ ▼
EOD
Reports PULSE Future UHD
Services
│
▼
LIHG Current & Future
GitHub Workflows
Enterprise
principle:
One
organization-controlled GitHub identity for UHD, with permissions expanded
deliberately by function as UHD capabilities grow—not credentials tied to
individual developers or individual projects.