Skip to content

Instantly share code, notes, and snippets.

@GuillaumeFalourd
Created May 29, 2024 21:21
Show Gist options
  • Save GuillaumeFalourd/bf84f6423cad6e6ec465b337090696e4 to your computer and use it in GitHub Desktop.
Save GuillaumeFalourd/bf84f6423cad6e6ec465b337090696e4 to your computer and use it in GitHub Desktop.

Using GitHub App to Install Private Repos Across Organizations

Using GitHub Apps to manage access to private repositories across organizations is indeed a more secure and scalable approach compared to using service accounts and SSH keys. GitHub Apps offer granular permissions, better security controls, and automated workflows. Here's a step-by-step guide on how to achieve this:

Step 1: Create a GitHub App

  1. Create the GitHub App in Org1:

    • Go to the Settings of Org1.
    • Select Developer settings and then GitHub Apps.
    • Click New GitHub App.
    • Fill out the details of your app (name, URL, etc.).
    • Set the required permissions. For this case, you need:
      • Repository permissions:
        • Contents: Read-only
      • Organization permissions:
        • Members: Read-only (optional, if needed)
    • Set Webhooks if needed (optional for this use case).
    • Generate a private key and save it securely. You'll need it later.
    • Save the app. You will get an App ID and Client ID/Client Secret.
  2. Install the GitHub App on Org1's Repo1:

    • After creating the app, you will see an option to Install App.
    • Install the app on the repositories you need (in this case, Repo1).
    • You will get an Installation ID. Save this as well.

Step 2: Access Private Repo from Org2

To install the private repository from Org1 in Org2 using the GitHub App, you need to create an access token using the app's credentials.

Create a JWT (JSON Web Token)

First, you need to create a JWT to authenticate as the GitHub App.

import jwt
import time

# Replace with your app's private key
private_key = b"""-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----"""

# Replace with your app ID
app_id = 'YOUR_APP_ID'

# Create the JWT payload
now = int(time.time())
payload = {
    'iat': now,
    'exp': now + (10 * 60),  # Token expiration time (10 minutes)
    'iss': app_id
}

# Create the JWT
jwt_token = jwt.encode(payload, private_key, algorithm='RS256')
print(jwt_token)

Create an Installation Access Token

Use the JWT to get an installation access token.

import requests

# Replace with your installation ID
installation_id = 'YOUR_INSTALLATION_ID'

# Replace with your GitHub App JWT token
headers = {
    'Authorization': f'Bearer {jwt_token}',
    'Accept': 'application/vnd.github.v3+json'
}

# Get the installation access token
response = requests.post(
    f'https://api.github.com/app/installations/{installation_id}/access_tokens',
    headers=headers
)

access_token = response.json()['token']
print(access_token)

Step 3: Use the Access Token to Install the Private Repo

Modify the pip install command in your Org2 repository to use the generated access token:

pip install git+https://<ACCESS_TOKEN>:x-oauth-basic@github.com/Org1/Repo1.git

Replace <ACCESS_TOKEN> with the token generated in the previous step. You can script this process in a GitHub Action or any CI/CD pipeline in Org2.

Automate Token Generation in GitHub Actions

You can use GitHub Actions in Org2 to automate the token generation and dependency installation:

  1. Create a GitHub Action Workflow in Org2:
name: Install Private Repo Dependency

on: [push]

jobs:
  install:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Generate JWT Token
        id: jwt
        run: |
          echo "JWT_TOKEN=$(python generate_jwt.py)" >> $GITHUB_ENV

      - name: Get Installation Access Token
        id: token
        run: |
          TOKEN=$(curl -X POST \
            -H "Authorization: Bearer ${{ env.JWT_TOKEN }}" \
            -H "Accept: application/vnd.github.v3+json" \
            https://api.github.com/app/installations/YOUR_INSTALLATION_ID/access_tokens | jq -r '.token')
          echo "ACCESS_TOKEN=$TOKEN" >> $GITHUB_ENV

      - name: Install Dependencies
        run: |
          pip install git+https://github.com/Org1/Repo1.git
        env:
          ACCESS_TOKEN: ${{ env.ACCESS_TOKEN }}

Replace YOUR_INSTALLATION_ID with your actual installation ID.

This workflow will:

  1. Generate a JWT token.
  2. Use the JWT token to get an installation access token.
  3. Use the access token to install the private repository.

Conclusion

Using GitHub Apps to manage access to private repositories across organizations provides a more secure and scalable approach. By following the steps outlined above, you can achieve seamless and secure integration of private repositories as dependencies in your projects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment