Automate Contributor License Agreement workflows for your GitHub repos.
CLA Bot is a self-hostable GitHub App that manages Contributor License Agreements for organizations and personal accounts. It enforces CLA compliance on pull requests, lets contributors sign and re-sign agreements, and gives admins full control over CLA text, versioning, and bypass lists.
- Automated PR enforcement — GitHub checks and comments block merging until the CLA is signed
- CLA versioning — text changes are tracked by SHA-256 hash; contributors are prompted to re-sign when the CLA is updated
- Admin dashboard — manage CLA text with live markdown preview, view signing history, configure bypass lists
- Contributor dashboard — view, sign, and download every CLA version
- Org-scoped bypass lists — exempt specific GitHub users, bots, and apps from CLA requirements
- Async PR sync — after signing, open PRs are automatically updated to passing
- GitHub-native auth — OAuth login, no separate account system
- Stateless sessions — JWT-based with HTTP-only cookies
Contributor opens PR
│
▼
GitHub webhook fires
│
▼
CLA Bot checks signature status
│
┌────┴────┐
│ │
Signed Not signed
│ │
▼ ▼
✅ Pass ❌ Fail + comment with signing link
│
▼
Contributor signs CLA
│
▼
✅ PR checks updated to pass
- Node.js >= 20
- pnpm
- PostgreSQL database
pnpm installCreate a .env.local file:
# Required
DATABASE_URL=postgres://user:pass@localhost:5432/clabot
SESSION_SECRET=your-secret-key
ENCRYPTION_KEY=your-encryption-key
# GitHub OAuth
GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
# GitHub App
GITHUB_APP_SLUG=...
GITHUB_APP_ID=...
GITHUB_PRIVATE_KEY=...
GITHUB_WEBHOOK_SECRET=...pnpm db:migratepnpm devThe app will be available at http://localhost:3000.
| Command | Description |
|---|---|
pnpm dev |
Start development server |
pnpm build |
Production build |
pnpm start |
Run production server |
pnpm lint |
Lint and format check (Biome) |
pnpm test |
Unit + integration tests |
pnpm test:all |
Unit + integration + E2E tests |
pnpm test:unit |
Unit tests (Vitest) |
pnpm test:integration |
Integration tests (Vitest + PostgreSQL) |
pnpm test:e2e |
Browser tests (Playwright) |
pnpm db:generate |
Generate Drizzle migrations |
pnpm db:migrate |
Apply migrations |
pnpm db:studio |
Open Drizzle Studio |
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router) |
| Language | TypeScript 5.7 (strict) |
| Database | PostgreSQL + Drizzle ORM |
| UI | Tailwind CSS, Radix UI, shadcn/ui |
| Auth | GitHub OAuth, JWT (jose) |
| GitHub API | Octokit |
| Testing | Vitest, Playwright |
| Linting | Biome |
| Deployment | Vercel |
app/
├── api/ # API routes (webhooks, auth, signing)
├── admin/ # Admin dashboard pages
├── contributor/ # Contributor dashboard pages
├── sign/ # CLA signing flow
└── auth/ # Authentication pages
lib/
├── db/ # Schema, queries, migrations
├── github/ # GitHub API client and webhook handling
├── cla/ # CLA signing and recheck workflows
├── security/ # Security utilities
└── auth.ts # Session management
components/
├── admin/ # Admin UI components
├── sign/ # Signing flow components
└── ui/ # Design system (shadcn/ui)
tests/
├── unit/ # Vitest unit tests
├── integration/ # API integration tests
└── e2e/ # Playwright browser tests
| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL connection string |
SESSION_SECRET |
JWT signing key |
ENCRYPTION_KEY |
OAuth token encryption key |
| Variable | Description |
|---|---|
GITHUB_CLIENT_ID |
OAuth app client ID |
GITHUB_CLIENT_SECRET |
OAuth app client secret |
GITHUB_APP_SLUG |
GitHub App slug |
GITHUB_APP_ID |
GitHub App ID |
GITHUB_PRIVATE_KEY |
GitHub App private key |
GITHUB_WEBHOOK_SECRET |
Webhook signature verification secret |
| Variable | Default | Description |
|---|---|---|
NEXT_PUBLIC_APP_URL |
Auto-detected | Override app base URL |
SEED_DATABASE |
false |
Auto-seed test data on startup |
DRIZZLE_MIGRATIONS_SCHEMA |
drizzle |
Migrations schema name |
DRIZZLE_MIGRATIONS_TABLE |
__drizzle_migrations |
Migrations table name |
For CLA enforcement to block merging, add CLA Bot / Contributor License Agreement as a required status check in your GitHub branch protection rules or rulesets.
Contributions are welcome! Please open an issue or pull request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/my-feature) - Run tests before submitting (
pnpm test && pnpm build) - Open a pull request