For production use, we recommend using a GitHub App instead of personal access tokens for better security, rate limits, and permissions management.
Why Use a GitHub App?¶
Better Rate Limits: 5,000 requests/hour per repository (vs 1,000 for PAT)
Fine-grained Permissions: Only grant what’s needed
Better Security: Scoped to specific repositories
Audit Trail: Track all app activities
No User Association: Operates independently
Creating the App¶
1. Create the App¶
Go to your organization settings:
https://github.com/organizations/QuantEcon/settings/appsClick “New GitHub App”
Fill in the details:
Name:
quantecon-style-guide-botHomepage URL:
https://github.com/QuantEcon/action-style-guideWebhook: Uncheck “Active” (we don’t need webhooks)
2. Set Permissions¶
Repository Permissions¶
Contents: Read & Write (for creating branches and committing)
Issues: Read (for reading issue comments)
Pull Requests: Read & Write (for creating PRs and comments)
Metadata: Read (automatically granted)
Where can this GitHub App be installed?¶
Select “Only on this account” (for QuantEcon organization).
3. Generate Private Key¶
After creating the app, scroll down to “Private keys”
Click “Generate a private key”
Save the downloaded
.pemfile securely
4. Install the App¶
Go to “Install App” in the left sidebar
Click “Install” next to your organization
Select repositories:
Choose “Only select repositories”
Select your lecture repositories (e.g.,
lecture-python-programming.myst)
Click “Install”
5. Get App Credentials¶
You’ll need:
App ID: Found in app settings (e.g.,
123456)Installation ID: Found in installation URL (e.g.,
https://github.com/settings/installations/98765)Private Key: The
.pemfile you downloaded
Using the App in Workflows¶
Recommended: actions/create-github-app-token¶
name: Style Guide Check
on:
issue_comment:
types: [created]
jobs:
review:
runs-on: ubuntu-latest
steps:
- name: Generate token
id: generate-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Run style guide checker
uses: QuantEcon/action-style-guide@v0.7
with:
mode: 'single'
github-token: ${{ steps.generate-token.outputs.token }}
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
comment-body: ${{ github.event.comment.body }}Manual Token Generation¶
For more control, generate the token manually:
- name: Generate App Token
id: app-token
run: |
TOKEN=$(curl -X POST \
-H "Authorization: Bearer $(ruby -e "require 'jwt'; puts JWT.encode({iat: Time.now.to_i, exp: Time.now.to_i + 60, iss: '${{ secrets.APP_ID }}'}, OpenSSL::PKey::RSA.new('${{ secrets.APP_PRIVATE_KEY }}'), 'RS256')")" \
-H "Accept: application/vnd.github+json" \
https://api.github.com/app/installations/${{ secrets.INSTALLATION_ID }}/access_tokens | jq -r .token)
echo "::add-mask::$TOKEN"
echo "token=$TOKEN" >> $GITHUB_OUTPUT
- name: Use token
uses: QuantEcon/action-style-guide@v0.7
with:
github-token: ${{ steps.app-token.outputs.token }}Setting Up Secrets¶
Go to Settings → Secrets and variables → Actions
Add repository secrets:
APP_ID— Your GitHub App IDAPP_PRIVATE_KEY— Contents of the.pemfileINSTALLATION_ID— Installation ID (optional, usually auto-detected)
Testing the Setup¶
Create a test issue in your repository
Comment:
@quantecon-style-guide test-lectureVerify:
The workflow triggers
A branch is created
A PR is opened
Labels applied correctly
Troubleshooting¶
“Resource not accessible by integration”¶
Cause: Missing repository permission
Fix: Go to app settings → Permissions → Grant required permission
“Bad credentials”¶
Cause: Invalid or expired token
Fix: Regenerate private key, update secret
“Not Found”¶
Cause: App not installed on repository
Fix: Go to app → Install App → Select repository
Rate Limits¶
| Token type | Limit |
|---|---|
| GitHub App | 5,000 requests/hour per repo |
| User access token | 15,000 requests/hour |
Check current rate limit:
curl -H "Authorization: Bearer $TOKEN" https://api.github.com/rate_limitSecurity Best Practices¶
Rotate Keys Regularly — Generate new private keys periodically
Minimum Permissions — Only grant necessary permissions
Scope Installation — Install only on required repositories
Monitor Activity — Review app activity logs regularly
Secure Storage — Store private key in GitHub Secrets, never commit