Skip to content

Setup GitOps GitHub App Authentication

Purpose

This guide explains how to create and configure a GitHub App for the automated promotion workflow that creates PRs to the cluster-gitops repository.

Why GitHub App Instead of PAT?

The promote-to-staging and promote-to-production jobs in the CI/CD workflow need to:

  1. Clone the cluster-gitops repository
  2. Modify environment values files
  3. Create pull requests to trigger ArgoCD deployments

Why not use GITHUB_TOKEN?

  • Default GITHUB_TOKEN has read-only access to external repositories
  • Cannot trigger workflows in other repositories (security feature)

Why not use PAT (Personal Access Token)?

  • Tied to individual user account (continuity issues if user leaves)
  • Broad permissions across all repositories user can access
  • Difficult to audit and track usage

Why GitHub App?

  • Repository-scoped permissions: Only access cluster-gitops, not all repos
  • Organization-level identity: Not tied to individual users
  • Fine-grained permissions: Specify exact permissions needed
  • Better audit trail: All actions show as performed by the app
  • No expiration: Unlike PATs, app credentials don't expire (though private keys can be rotated)
  • Can trigger workflows: Unlike GITHUB_TOKEN, can trigger workflows in target repos

Prerequisites

  • Organization admin or appropriate permissions to create GitHub Apps
  • Access to organization settings
  • Basic understanding of public/private key cryptography

Creating the GitHub App

Step 1: Create New GitHub App

  1. Go to Organization SettingsDeveloper settingsGitHub Apps

Direct link: https://github.com/organizations/{org-name}/settings/apps

  1. Click New GitHub App

  2. Configure the app:

Basic Information: - GitHub App name: SyRF GitOps Automation (must be unique across GitHub) - Description: Automated deployment promotions to cluster-gitops repository - Homepage URL: https://github.com/camaradesuk/syrf

Webhook: - Active: ❌ Uncheck (we don't need webhooks)

Permissions (Repository permissions): - Contents: Read and write (clone repo, push changes) - Pull requests: Read and write (create PRs) - Metadata: Read-only (automatically selected)

Where can this GitHub App be installed?: - ✅ Only on this account (recommended for security)

  1. Click Create GitHub App

Step 2: Generate Private Key

  1. After creating the app, scroll to Private keys section

  2. Click Generate a private key

  3. A .pem file will be downloaded automatically

  4. IMPORTANT: Store this file securely - you'll need it for the secrets

Step 3: Install the App on cluster-gitops Repository

  1. On the GitHub App settings page, click Install App (left sidebar)

  2. Click Install next to your organization name

  3. Select Only select repositories

  4. Choose: cluster-gitops

  5. Click Install

  6. Note the App ID from the GitHub App settings page (you'll need this)

Step 4: Add Secrets to syrf Repository

  1. Go to syrf repository settings:

https://github.com/camaradesuk/syrf/settings/secrets/actions

  1. Click New repository secret

  2. Add APP_ID:

  3. Name: APP_ID
  4. Value: The App ID from Step 3 (e.g., 123456)
  5. Click Add secret

  6. Add APP_PRIVATE_KEY:

  7. Name: APP_PRIVATE_KEY
  8. Value: Contents of the .pem file from Step 2

    # Copy the entire contents including headers:
    -----BEGIN RSA PRIVATE KEY-----
    MIIEpAIBAAKCAQEA...
    ...
    -----END RSA PRIVATE KEY-----
    
  9. Click Add secret

Step 5: Verify Secrets are Available

  1. Go to: https://github.com/camaradesuk/syrf/settings/secrets/actions

  2. Verify both secrets appear:

  3. APP_ID
  4. APP_PRIVATE_KEY

How It Works in the Workflow

The workflow uses the actions/create-github-app-token action to generate a short-lived token:

- name: Generate GitHub App Token
  id: app-token
  uses: actions/create-github-app-token@v1
  with:
    app-id: ${{ secrets.APP_ID }}
    private-key: ${{ secrets.APP_PRIVATE_KEY }}
    repositories: cluster-gitops  # Only access this repo

This token is then used for checkout and PR creation:

- name: Checkout cluster-gitops
  uses: actions/checkout@v4
  with:
    repository: camaradesuk/cluster-gitops
    token: ${{ steps.app-token.outputs.token }}
    path: cluster-gitops

- name: Create Pull Request
  uses: peter-evans/create-pull-request@v5
  with:
    token: ${{ steps.app-token.outputs.token }}
    path: cluster-gitops
    # ... other configuration

Key Points:

  • Token is generated fresh for each workflow run
  • Token expires after 1 hour (short-lived for security)
  • Token is scoped to only the cluster-gitops repository
  • Actions performed by the token show as done by "SyRF GitOps Automation[bot]"

Security Considerations

Permissions (Principle of Least Privilege)

The app has only the permissions it needs:

  • Contents: Read and write - Clone and push to cluster-gitops
  • Pull requests: Read and write - Create promotion PRs
  • NOT granted: Issues, Actions, Administration, etc.

Repository Scope

  • App is installed only on cluster-gitops repository
  • Cannot access any other repositories in the organization
  • If you need access to additional repos, must explicitly install there

Private Key Security

The .pem private key is the most sensitive component:

  1. Never commit the .pem file to git
  2. Store securely in a password manager or secrets vault
  3. Rotate regularly (see Rotation Strategy below)
  4. Revoke immediately if compromised

Audit Trail

All actions performed by the app are logged:

  • GitHub Audit Log shows app activity
  • Commits show author as "SyRF GitOps Automation[bot]"
  • PRs show creator as the app
  • Easy to identify automated vs manual changes

Rotation Strategy

When to Rotate Private Key

  • Every 90 days (recommended best practice)
  • Immediately if key is potentially compromised
  • Before team member leaves (if they had access to the key)
  • After security incident in the organization

How to Rotate Private Key

  1. Generate new private key:
  2. Go to GitHub App settings
  3. Scroll to Private keys
  4. Click Generate a private key
  5. Download the new .pem file

  6. Update secret:

  7. Go to syrf repository secrets
  8. Click Update on APP_PRIVATE_KEY
  9. Paste contents of new .pem file
  10. Click Update secret

  11. Test workflow:

  12. Trigger a test workflow run
  13. Verify promotion still works
  14. Check PR is created successfully

  15. Revoke old key:

  16. Go to GitHub App settings → Private keys
  17. Click Delete on the old key
  18. Confirm deletion

Important: Have the new key working before revoking the old one!

Troubleshooting

Error: "Resource not accessible by integration"

Cause: App doesn't have required permissions

Fix:

  1. Go to GitHub App settings → Permissions
  2. Verify Contents and Pull requests are set to "Read and write"
  3. Click Save changes
  4. Approve the permission change (organization admins may need to approve)

Error: "Bad credentials" or "Authentication failed"

Cause: Invalid APP_ID or APP_PRIVATE_KEY

Fix:

  1. Verify APP_ID matches the App ID in GitHub App settings
  2. Verify APP_PRIVATE_KEY contains the full .pem file contents
  3. Check for extra spaces or newlines when copying
  4. Regenerate private key if necessary

Error: "App is not installed on repository"

Cause: GitHub App not installed on cluster-gitops

Fix:

  1. Go to GitHub App settings → Install App
  2. Verify app is installed on cluster-gitops repository
  3. If not, click Install and select cluster-gitops

PR Creation Shows Wrong Author

Expected: PRs should show "SyRF GitOps Automation[bot]" as creator

If showing user account instead:

  • Workflow might be using GITHUB_TOKEN instead of app token
  • Verify workflow uses ${{ steps.app-token.outputs.token }}

Token Generation Fails

Error: "Failed to create installation access token"

Fix:

  1. Check app is installed on target repository
  2. Verify repositories: parameter matches installation
  3. Ensure organization didn't revoke app access
  4. Check app isn't suspended or disabled

Testing the Setup

After configuring the secrets, test the GitHub App authentication:

Test 1: Verify Secrets

# This will fail if secrets aren't configured
gh secret list --repo camaradesuk/syrf | grep -E "APP_ID|APP_PRIVATE_KEY"

Expected output:

APP_ID                  Updated 2025-11-21
APP_PRIVATE_KEY         Updated 2025-11-21

Test 2: Trigger Promotion Workflow

  1. Make a small change to any service:
echo "# Test GitHub App authentication" >> src/services/api/README.md
git add .
git commit -m "test: verify GitHub App authentication"
git push origin main
  1. Monitor workflow run:
  2. Go to: https://github.com/camaradesuk/syrf/actions
  3. Watch for promote-to-staging job
  4. Should succeed without errors

  5. Check PR in cluster-gitops:

  6. Go to: https://github.com/camaradesuk/cluster-gitops/pulls
  7. Verify PR was created
  8. Check author shows as "SyRF GitOps Automation[bot]"

Test 3: Verify App Audit Trail

  1. Go to: https://github.com/organizations/{org-name}/settings/audit-log
  2. Filter by: action:git.clone actor:syrf-gitops-automation
  3. Should see app activity for checkout and PR creation

Comparison: GitHub App vs PAT

Feature GitHub App ✅ PAT (Personal Access Token)
Scoped to specific repos ✅ Yes ❌ No (all repos user can access)
Organization-level identity ✅ Yes ❌ No (tied to user)
Fine-grained permissions ✅ Yes ⚠️ Limited (PAT scopes are broad)
Audit trail ✅ Clear (bot account) ⚠️ Mixed with user activity
Expiration ✅ No expiration ❌ Must renew periodically
Can trigger workflows ✅ Yes ✅ Yes
Survives user leaving ✅ Yes ❌ No (token deleted)
Setup complexity ⚠️ More complex ✅ Simpler

Verdict: GitHub App is more secure and maintainable for production use.

Migration from PAT (If Previously Used)

If you previously used GITOPS_PAT, here's how to migrate:

  1. Set up GitHub App (follow steps above)
  2. Update workflow (already done - uses APP_ID and APP_PRIVATE_KEY)
  3. Test new setup (follow Testing section)
  4. Remove old PAT secret:
  5. Go to repository secrets
  6. Delete GITOPS_PAT
  7. Revoke PAT:
  8. Go to: https://github.com/settings/tokens
  9. Find "GitOps Cluster Deployment Automation" token
  10. Click Delete

Maintenance Checklist

Monthly

  • ✅ Verify app is still installed on cluster-gitops
  • ✅ Check recent workflow runs succeeded
  • ✅ Review audit log for unexpected activity

Quarterly

  • ✅ Review app permissions (are they still minimal?)
  • ✅ Consider rotating private key
  • ✅ Verify only necessary repositories have app installed

Annually

  • ✅ Rotate private key (mandatory)
  • ✅ Review GitHub App security best practices
  • ✅ Audit all organization GitHub Apps

Support

If you encounter issues:

  1. Check Troubleshooting section above
  2. Review workflow logs: https://github.com/camaradesuk/syrf/actions
  3. Check GitHub Status: https://www.githubstatus.com/
  4. Review audit log for app activity
  5. Create issue in syrf repository with error details