- Purpose: Used for OAuth authentication (user login)
- Where: GitHub OAuth App settings
- Environment Variable:
GITHUB_OAUTH_CLIENT_SECRET - Used for: User authentication flows
- Purpose: Verifies webhook payloads are from GitHub
- Where: GitHub App settings → Webhook section
- Environment Variable:
GITHUB_WEBHOOK_SECRET - Used for: Verifying webhook requests
openssl rand -hex 32- Use any secure random string generator
- Minimum 32 characters
- Example: https://www.random.org/strings/
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"python3 -c "import secrets; print(secrets.token_hex(32))"-
Generate a new random secret:
openssl rand -hex 32
-
Copy the output (it will look like):
a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6 -
Add to GitHub App Settings:
- Go to your GitHub App → Webhook section
- Paste the secret in the "Secret" field
- Click "Update GitHub App"
-
Add to Environment Variables:
GITHUB_WEBHOOK_SECRET=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6
✅ DO:
- Generate a NEW random secret for webhooks
- Use a different secret than your OAuth Client Secret
- Keep it secure (don't commit to git)
- Use the same secret in both GitHub App settings AND your backend
❌ DON'T:
- Use your OAuth Client Secret as the webhook secret
- Reuse the same secret for multiple purposes
- Share the secret publicly
- Commit it to version control
- Security Best Practice: Different secrets for different purposes
- Separation of Concerns: OAuth handles authentication, webhooks handle events
- Flexibility: You can rotate them independently
- GitHub Requirement: GitHub requires a separate webhook secret
After setting up:
- GitHub will sign webhook payloads with this secret
- Your backend verifies the signature using
GITHUB_WEBHOOK_SECRET - If they don't match, webhook requests are rejected (security feature)
TL;DR: Generate a NEW random secret for webhooks. Don't use your OAuth Client Secret.