A scalable, serverless GitHub App bot built with Probot and deployed on Vercel. The bot automates repository management tasks, handles pull requests, issues, and provides automated responses to repository events.
- Pull Request Management: Welcome messages, automated comments, and labeling
- Issue Handling: Auto-labeling based on content, welcome messages
- Review Management: Automatic labeling based on review states
- Repository Setup: Initial structure creation for new repositories
- Serverless Deployment: No server maintenance required with Vercel
- Secure Configuration: Environment variables for all sensitive data
holonbot/
├── api/
│ ├── github-webhook.js # Vercel serverless function (webhook handler)
│ └── exchange-token.js # Vercel serverless function (OIDC token exchange)
├── lib/
│ ├── bot-handler.js # Core bot logic
│ ├── oidc.js # OIDC token verification
│ └── probot-client.js # Shared Probot instance
├── package.json # Dependencies and scripts
├── vercel.json # Vercel configuration
└── README.md # This file
- Node.js 18+ (for local development)
- GitHub account with appropriate permissions
- Vercel account (for deployment)
- GitHub App credentials
- Go to GitHub Developer Settings
- Click "New GitHub App"
- Configure the app:
- App name:
HolonBot(or your preferred name) - Homepage URL: Your project's homepage
- Webhook URL:
https://your-vercel-domain.vercel.app/api/github-webhook(placeholder for now) - Webhook secret: Generate a strong random string (save this!)
- App name:
Under Repository permissions, set:
| Permission | Access | Purpose |
|---|---|---|
| Issues | Read & Write | Create comments and add labels |
| Pull Requests | Read & Write | Create comments and manage PRs |
| Checks | Read & Write | Handle check runs |
| Metadata | Read | Access repository information |
| Contents | Write | Create initial repository files |
Under Subscribe to events, select:
- Pull requests
- Issues
- Pull request reviews
- Repository creation
- Check runs
- Save the App ID (displayed in the app settings)
- Generate a Private Key and download the
.pemfile - Save the Webhook secret you generated earlier
- Install the GitHub App on your target repositories
- Note which repositories you want the bot to work on
git clone <your-repo-url>
cd holonbot
npm installCreate a .env file with your GitHub App credentials:
APP_ID=your_app_id_here
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----\n"
WEBHOOK_SECRET=your_webhook_secret_here
NODE_ENV=development
LOG_LEVEL=debug
HOLON_OIDC_AUDIENCE=holon-token-brokernpm run devThe bot will start and be ready to receive webhook events. Use a tool like ngrok to expose your local server to GitHub during development.
ngrok http 3000Update your GitHub App's webhook URL to use the ngrok URL.
npm i -g vercelvercel loginvercel --prodGo to your Vercel project dashboard and add these environment variables:
APP_ID=your_app_id_here
PRIVATE_KEY=your_private_key_content_here
WEBHOOK_SECRET=your_webhook_secret_here
NODE_ENV=production
LOG_LEVEL=info
Important: For the PRIVATE_KEY, include the entire key content including the -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- lines, with \n characters for line breaks.
- Go back to your GitHub App settings
- Update the Webhook URL to:
https://your-vercel-domain.vercel.app/api/github-webhook - Click "Save changes"
api/exchange-token.js is hardened for GitHub Actions OIDC to GitHub App installation token exchange.
- OIDC JWT verification enforces:
- signature via GitHub JWKS
iss=https://token.actions.githubusercontent.comaudin configured audiences (HOLON_OIDC_AUDIENCE, default:holon-token-broker)- standard JWT time checks (
exp,nbf)
- Claim validation enforces repository binding:
repository/repository_ownerformat and consistencyrepository_idpresent and numericsubstarts withrepo:<owner>/<repo>:
- Token issuance is bound to the same repository:
- broker fetches repo and verifies
repository_id - installation token is scoped with
repository_ids: [repo.id]
- broker fetches repo and verifies
- Default policy requires actor collaborator/member check before issuing token.
job_workflow_refcan be required and restricted by allowlist.- Replay protection denies duplicate
jti/run_idwithin a TTL window. - Rate limiting throttles repeated requests by
(repository, actor). - Installation token defaults to least privilege:
contents: writepull_requests: write
Optional (defaults shown):
-
HOLON_OIDC_AUDIENCE=holon-token-broker(comma-separated accepted OIDC audiences) -
HOLON_REQUIRE_ACTOR_COLLABORATOR=true -
HOLON_MIN_ACTOR_PERMISSION=read -
HOLON_REQUIRE_JOB_WORKFLOW_REF=true -
HOLON_ALLOWED_WORKFLOW_REFS=(comma-separated exact refs) -
HOLON_REQUIRE_DEFAULT_BRANCH_REF=true -
HOLON_ALLOW_PULL_REQUEST_REF=true(when default-branch enforcement is on, also allowrefs/pull/*/(merge|head)) -
HOLON_ENABLE_REPLAY_PROTECTION=true -
HOLON_REPLAY_WINDOW_SECONDS=3600 -
HOLON_ENABLE_RATE_LIMIT=true -
HOLON_RATE_LIMIT_WINDOW_SECONDS=60 -
HOLON_RATE_LIMIT_MAX_REQUESTS=10 -
HOLON_INSTALLATION_PERMISSIONS_JSON=(JSON object; default is{"contents":"write","pull_requests":"write"})
- Opened/Reopened: Bot posts a welcome message with checklist
- Review Submitted:
- Approved: Adds
approvedlabel - Changes Requested: Adds
changes-requestedlabel
- Approved: Adds
- Opened: Bot posts a welcome message
- Auto-labeling: Automatically adds labels based on content:
bug- for bug reportsenhancement- for feature requestsquestion- for questions
- Created: Sets up initial repository structure with README.md and .gitignore
- Vercel Logs: Access real-time logs from your Vercel dashboard
- GitHub App Logs: Monitor webhook delivery status in GitHub App settings
- Local Logs: Use
LOG_LEVEL=debugfor detailed local development logs
- ✅ All secrets stored in environment variables
- ✅ Webhook signature verification enabled
- ✅ Minimal permissions requested
- ✅ No sensitive data in codebase
- ✅ HTTPS enforced by Vercel
- 403 Forbidden: Check GitHub App permissions and installation
- Webhook delivery failures: Verify webhook URL and secret
- Environment variables missing: Ensure all required variables are set in Vercel
- Function timeouts: Check Vercel function logs and increase duration if needed
# Test webhook delivery
curl -X POST https://your-app.vercel.app/api/github-webhook \
-H "Content-Type: application/json" \
-H "X-GitHub-Event: ping" \
-H "X-Hub-Signature-256: sha256=..." \
-d '{"zen": "Non-blocking is better than blocking."}'- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
MIT License - see LICENSE file for details.
For issues and questions:
- Check the troubleshooting section above
- Review Vercel function logs
- Check GitHub App delivery logs
- Open an issue in this repository