🔓 100% Open Source | 🤖 Bring Your Own LLM | 🚀 Self-Hosted Kubernetes Risk Analysis
Stop preventable production incidents before they happen
After one too many 3am pages from production incidents that could've been caught earlier, I built PatchPulse. It's a self-hosted tool that analyzes your Kubernetes changes before they hit production, combining rule-based guardrails with optional AI analysis to give you explainable risk scores.
Think of it as a safety net for your deployments - it catches the stuff that slips through code review and CI/CD checks.
I've been there - you merge a PR, deploy to production, and suddenly pods are OOMKilled because someone forgot resource limits. Or worse, a security misconfiguration opens up your cluster. PatchPulse catches these issues before they become incidents.
- 🛡️ Catch Problems Early: See risky changes before they reach production
- 🔍 Understand Why: Get clear explanations when something's flagged
- 🤖 Optional AI: Use AI for deeper analysis, or skip it entirely - your call
- ⚡ Real-Time Alerts: Know immediately when something's wrong
- 🔓 100% Open Source: No vendor lock-in, no SaaS fees, just code you can trust
- 🏠 Your Data, Your Control: Everything runs on your infrastructure
- 🔓 Fully Open Source - Non-commercial license, no vendor lock-in
- 🤖 Bring Your Own LLM - Use OpenAI, DeepSeek, Claude, Gemini, or any OpenAI-compatible API
- 🏠 Self-Hosted - Your data stays on your infrastructure
- 🛡️ 11+ Guardrails - Rule-based checks for Kubernetes best practices
- 🧠 AI-Powered Analysis - Security scanning, recommendations, incident prediction
- ⚡ Real-Time - WebSocket updates and instant notifications
- 🔌 Integrations - GitHub, GitLab, Slack, Teams, PagerDuty, Email
- 📊 Enterprise Features - Admission webhooks, policy bundles, SBOM verification, multi-tenancy
- Resource Limits - Ensures CPU/memory limits are set
- Resource Requests - Validates resource requests are configured
- Readiness Probes - Checks for readiness probe configuration
- Liveness Probes - Validates liveness probe setup
- Security Context - Enforces security context settings
- Image Tags - Prevents
latesttag usage - Namespace Validation - Ensures proper namespace usage
- Service Account - Validates service account configuration
- Network Policies - Checks network policy compliance
- Resource Quotas - Validates resource quota adherence
- Pod Disruption Budgets - Ensures PDB configuration
- Docker (running) - Required for containerized deployment
- Python 3.11+ - For local development
- Go 1.21+ - For agent development (optional)
- kubectl - For Kubernetes integration (optional)
git clone https://github.com/amarkdotdev/patchpulse.git
cd patchpulsePatchPulse supports multiple AI providers. You only need to provide an API key for ONE provider:
# Create .env file
touch .env
# Option 1: OpenAI (recommended for best results)
echo "OPENAI_API_KEY=sk-your-key-here" >> .env
# Option 2: DeepSeek (cost-effective alternative)
# echo "DEEPSEEK_API_KEY=sk-your-key-here" >> .env
# Option 3: Claude (Anthropic)
# echo "ANTHROPIC_API_KEY=sk-ant-your-key-here" >> .env
# Note: Requires: pip install anthropic
# Option 4: Google Gemini
# echo "GEMINI_API_KEY=your-key-here" >> .env
# Note: Requires: pip install google-generativeai
# Optionally specify which provider to use (defaults to first available)
# echo "AI_PROVIDER=openai" >> .env💡 No LLM? No Problem! PatchPulse works perfectly fine without any AI - you'll still get all the rule-based guardrails and risk scoring. The AI stuff is just extra if you want it.
# Start all services
docker compose up -d
# Check logs
docker compose logs -f backend
# Wait for services to be ready (about 10-15 seconds)Once PatchPulse is running, access it at:
-
Dashboard: http://localhost:8000/dashboard
- Main user interface for monitoring decisions, viewing analytics, and managing configurations
- Real-time updates via WebSocket
- Risk visualization and decision history
-
API Documentation: http://localhost:8000/docs
- Interactive Swagger/OpenAPI documentation
- Test API endpoints directly from the browser
- Full API reference
-
Health Check: http://localhost:8000/health
- Service health status
- Database connectivity check
-
API Root: http://localhost:8000/api
- API information and available endpoints
- Access the Dashboard: Open http://localhost:8000/dashboard in your browser
- View Decisions: See real-time risk analysis and decisions
- Configure Integrations: Set up GitHub, GitLab, Slack, or other integrations via the API
- Monitor Analytics: Track risk trends, blocked changes, and system health
Note: The dashboard is the main interface for PatchPulse. The website (patchpulse.dev) is a separate marketing site and not part of this repository.
PatchPulse can be deployed in two ways:
Backend runs separately (Docker Compose, VM, or anywhere):
- Backend service runs independently
- Agent runs outside your Kubernetes cluster
- Agent connects to your cluster using
kubeconfig - Best for: Testing, development, or when you don't want to deploy into your cluster
# 1. Start backend (runs anywhere)
docker compose up -d
# 2. Run agent locally (connects to your cluster via kubeconfig)
cd app/agent
export BACKEND_URL=http://localhost:8000
export KUBECONFIG=$HOME/.kube/config # Points to your cluster
go run cmd/agent/main.goBoth backend and agent run inside Kubernetes:
- Backend deployed as a Kubernetes Deployment
- Agent deployed in the same or different namespace
- Agent uses in-cluster config (ServiceAccount)
- Best for: Production deployments, full integration
# Deploy both backend and agent to your cluster
helm install patchpulse-backend ./helm/backend --namespace patchpulse
helm install patchpulse-agent ./helm/agent --namespace patchpulsePatchPulse works in two ways:
- Monitors GitHub/GitLab PRs/MRs
- Analyzes Kubernetes manifests in diffs
- Evaluates guardrails before code is merged
- Sends notifications if risky changes detected
# Example: PR with risky deployment.yaml
# PatchPulse detects: "Missing resource limits"
# → Risk score: 50
# → Decision: Advisory (allows, but warns)- Agent watches your Kubernetes cluster
- Collects deployment signals, pod events, node status
- Detects issues in running workloads
- Provides real-time cluster health insights
┌─────────────────┐
│ Developer │
│ Creates PR │
└────────┬────────┘
│
▼
┌─────────────────┐ ┌──────────────────┐
│ Git Integration│────▶│ PatchPulse │
│ (GitHub/GitLab)│ │ Backend │
└─────────────────┘ │ (FastAPI) │
└────────┬─────────┘
│
┌────────▼─────────┐
│ Policy Engine │
│ + AI Analysis │
└────────┬─────────┘
│
┌────────▼─────────┐
│ Risk Score │
│ Decision │
└────────┬─────────┘
│
┌───────────────────────┼───────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Notification │ │ Dashboard │ │ Kubernetes │
│ (Slack/Email) │ │ (Web UI) │ │ Agent │
└─────────────────┘ └─────────────────┘ └────────┬────────┘
│
▼
┌─────────────────┐
│ Your K8s │
│ Cluster │
└─────────────────┘
- Ensure you have access to your cluster:
# Test cluster access
kubectl get nodes
# If using a remote cluster, make sure kubeconfig is set
export KUBECONFIG=$HOME/.kube/config- Start the agent pointing to your cluster:
# The agent will automatically use your kubeconfig
export BACKEND_URL=http://localhost:8000 # Where backend is running
cd app/agent
go run cmd/agent/main.go- Deploy PatchPulse to your cluster:
# Create namespace
kubectl create namespace patchpulse
# Deploy backend
helm install patchpulse-backend ./helm/backend \
--namespace patchpulse \
--set env.DATABASE_URL="postgresql://..."
# Deploy agent (automatically connects to cluster)
helm install patchpulse-agent ./helm/agent \
--namespace patchpulse \
--set env.BACKEND_URL="http://patchpulse-backend:8000"- The agent automatically uses in-cluster config (no kubeconfig needed)
- Kubernetes manifests (Deployments, Services, ConfigMaps, etc.)
- Changes to resource limits, requests, probes
- Security context changes
- Image tag updates
- Network policy changes
- Deployment availability and replica counts
- Pod restart counts
- Node readiness status
- Warning events
- Resource utilization trends
- Architecture
- Configuration
- LLM Provider Setup
- API Usage
- Deployment
- Development
- Use Cases
- Contributing
- Support
- License
- REST API for change events and decisions
- Policy engine with 11+ guardrails
- AI-powered risk analysis (bring your own LLM!)
- PostgreSQL database for persistence
- WebSocket support for real-time updates
- Kubernetes cluster monitoring
- Resource snapshotting
- Event watching
- Least-privilege RBAC
- GitHub PR analysis
- GitLab MR analysis
- Diff parsing and manifest extraction
- Slack notifications with interactive approval buttons
- Email notifications
- Microsoft Teams integration
- PagerDuty integration
- Real-time decision monitoring via WebSocket
- Risk visualization and analytics
- Decision history and filtering
- Export functionality (CSV/JSON)
- Accessible at
/dashboardendpoint
1. Developer creates PR/MR → Git integration detects change
2. Change event sent to backend → Policy engine evaluates
3. AI analysis runs (if configured) → Security scan, recommendations, predictions
4. Risk score calculated (0-100) → Decision made (allow/block)
5. Notification sent to Slack/Teams → Decision stored in database
6. Dashboard updates in real-time via WebSocket
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ GitHub │────▶│ Git Poller │────▶│ Backend │
│ GitLab │ │ │ │ (FastAPI) │
└─────────────┘ └──────────────┘ └──────┬──────┘
│
┌─────────────┐ ┌──────────────┐ │
│ Kubernetes │────▶│ Agent │─────────────┘
│ Cluster │ │ (Go) │
└─────────────┘ └──────────────┘
│
┌─────────────┐ ┌──────────────┐ ┌─────▼──────┐
│ Slack │◀────│ Notifications│◀────│ PostgreSQL │
│ Teams │ │ │ │ Database │
│ PagerDuty │ └──────────────┘ └────────────┘
│ Email │
└─────────────┘
Create a .env file in the root directory:
# Database
DATABASE_URL=postgresql://patchpulse:patchpulse@postgres:5432/patchpulse
# Policy Mode (advisory or enforce)
POLICY_MODE=advisory
# Logging
LOG_LEVEL=INFO
# AI Provider - Choose ONE (see LLM Provider Setup section)
OPENAI_API_KEY=your_openai_api_key
# OR
# DEEPSEEK_API_KEY=your_deepseek_api_key
# OR
# ANTHROPIC_API_KEY=your_anthropic_api_key
# OR
# GEMINI_API_KEY=your_gemini_api_key
# Optional: Specify which provider to use (defaults to first available)
AI_PROVIDER=openai
# Git Integration
GITHUB_TOKEN=your_github_token
GITHUB_REPOS=owner/repo1,owner/repo2
GITLAB_TOKEN=your_gitlab_token
GITLAB_PROJECTS=12345,67890
# JWT Secret (auto-generated if not set)
JWT_SECRET_KEY=your_jwt_secret-
advisory: Logs decisions but doesn't block changes (default)- Best for: Testing, gradual rollout, learning mode
- All decisions are logged and visible in dashboard
- No changes are blocked
-
enforce: Blocks high-risk changes (score ≥ 70)- Best for: Production environments
- High-risk changes are automatically blocked
- Requires manual approval for blocked changes
PatchPulse is 100% open source and supports bring your own LLM. You can use any of these providers:
| Provider | Cost | Quality | Setup |
|---|---|---|---|
| OpenAI | $$$ | ⭐⭐⭐⭐⭐ | OPENAI_API_KEY=sk-... |
| DeepSeek | $ | ⭐⭐⭐⭐ | DEEPSEEK_API_KEY=sk-... |
| Claude | $$$ | ⭐⭐⭐⭐⭐ | ANTHROPIC_API_KEY=sk-ant-... |
| Gemini | $$ | ⭐⭐⭐⭐ | GEMINI_API_KEY=... |
export OPENAI_API_KEY=sk-your-key-here
# Or in .env file:
echo "OPENAI_API_KEY=sk-your-key-here" >> .envModels: Uses gpt-4o-mini by default (cost-effective). You can modify ai_analyzer.py to use other models.
export DEEPSEEK_API_KEY=sk-your-key-here
# Or in .env file:
echo "DEEPSEEK_API_KEY=sk-your-key-here" >> .envModels: Uses deepseek-chat by default. OpenAI-compatible API.
# First install the package
pip install anthropic
export ANTHROPIC_API_KEY=sk-ant-your-key-here
# Or in .env file:
echo "ANTHROPIC_API_KEY=sk-ant-your-key-here" >> .envModels: Uses claude-3-5-sonnet-20241022 by default.
# First install the package
pip install google-generativeai
export GEMINI_API_KEY=your-key-here
# Or in .env file:
echo "GEMINI_API_KEY=your-key-here" >> .envModels: Uses gemini-1.5-pro by default.
PatchPulse supports any OpenAI-compatible API endpoint (Ollama, LocalAI, vLLM, etc.):
# Set a dummy API key (not used for local endpoints)
export OPENAI_API_KEY=not-used
# Set your custom endpoint
export OPENAI_BASE_URL=http://localhost:11434/v1 # Ollama example
# Or
export OPENAI_BASE_URL=http://localhost:8080/v1 # LocalAI example
# Or in .env file:
echo "OPENAI_API_KEY=not-used" >> .env
echo "OPENAI_BASE_URL=http://localhost:11434/v1" >> .envExamples:
- Ollama:
OPENAI_BASE_URL=http://localhost:11434/v1 - LocalAI:
OPENAI_BASE_URL=http://localhost:8080/v1 - vLLM:
OPENAI_BASE_URL=http://localhost:8000/v1 - Any OpenAI-compatible service: Just set the base URL!
The system will automatically use your custom endpoint with the OpenAI client.
PatchPulse works perfectly without any LLM! If no API key is provided:
- ✅ All rule-based guardrails work
- ✅ Risk scoring works
- ✅ All integrations work
- ✅ Dashboard works
⚠️ AI-powered features are disabled (security scanning, recommendations, predictions)
curl -X POST http://localhost:8000/api/v1/change-events \
-H "Content-Type: application/json" \
-d '{
"source": "github",
"repo": "org/repo",
"sha": "abc123",
"pr_number": 42,
"branch": "feature-branch",
"files": ["k8s/deployment.yaml"],
"diff_hunks": [{
"file": "k8s/deployment.yaml",
"hunk": "- limits:\n cpu: 500m"
}],
"timestamp": "2026-01-01T00:00:00Z"
}'curl http://localhost:8000/api/v1/decisions?limit=10curl http://localhost:8000/api/v1/analytics/summarycurl http://localhost:8000/api/v1/decisions/{decision_id}# Filter by risk score
curl "http://localhost:8000/api/v1/decisions?min_risk=50&max_risk=100"
# Filter by source
curl "http://localhost:8000/api/v1/decisions?source=github"
# Filter by date range
curl "http://localhost:8000/api/v1/decisions?start_date=2026-01-01&end_date=2026-01-31"See /docs for interactive API documentation.
docker compose up -dOption 1: Using your .env file (Recommended)
# Create a values file from your .env
# This reads your .env file and creates Helm values
cat > /tmp/patchpulse-values.yaml <<EOF
env:
DATABASE_URL: "postgresql://patchpulse:patchpulse@postgres:5432/patchpulse"
POLICY_MODE: "advisory"
LOG_LEVEL: "INFO"
OPENAI_API_KEY: "$(grep OPENAI_API_KEY .env | cut -d '=' -f2)"
DEEPSEEK_API_KEY: "$(grep DEEPSEEK_API_KEY .env | cut -d '=' -f2 || echo '')"
ANTHROPIC_API_KEY: "$(grep ANTHROPIC_API_KEY .env | cut -d '=' -f2 || echo '')"
GEMINI_API_KEY: "$(grep GEMINI_API_KEY .env | cut -d '=' -f2 || echo '')"
EOF
# Install backend using values from .env
helm install patchpulse-backend ./helm/backend \
--namespace patchpulse \
--create-namespace \
--values /tmp/patchpulse-values.yaml
# Install agent
helm install patchpulse-agent ./helm/agent \
--namespace patchpulse \
--set env.BACKEND_URL=http://patchpulse-backend:8000Option 2: Using --set-file (Alternative)
# Install backend with API key from .env file
helm install patchpulse-backend ./helm/backend \
--namespace patchpulse \
--create-namespace \
--set env.OPENAI_API_KEY="$(grep OPENAI_API_KEY .env | cut -d '=' -f2)" \
--set env.POLICY_MODE=advisory
# Install agent
helm install patchpulse-agent ./helm/agent \
--namespace patchpulse \
--set env.BACKEND_URL=http://patchpulse-backend:8000Option 3: Manual values override
Edit helm/backend/values.yaml and add your API keys to the env section, then install:
helm install patchpulse-backend ./helm/backend \
--namespace patchpulse \
--create-namespace- Use environment variables for secrets (never hardcode)
- Set up proper TLS/SSL certificates
- Configure database backups
- Set up monitoring and alerting
- Use a managed PostgreSQL database for production
- Configure rate limiting
- Set up log aggregation
- Enable audit logging
# Backend
cd app/backend
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
uvicorn main:app --reload
# Agent
cd app/agent
go run cmd/agent/main.go
# Git Integration
cd app/integrations/git
python poller.py# Unit tests
cd app/backend
pytest tests/
# Integration tests
docker compose up -d
./test_api_endpoints.shpatchpulse/
├── app/ # Application code
│ ├── backend/ # FastAPI backend service
│ │ ├── main.py # Main application entry point
│ │ ├── models.py # Pydantic models and SQLAlchemy ORM
│ │ ├── database.py # Database connection and setup
│ │ ├── policy_engine.py # Policy evaluation and guardrails
│ │ ├── ai_analyzer.py # AI-powered risk analysis (BYO LLM!)
│ │ ├── ai_features.py # Advanced AI features
│ │ ├── auth.py # Authentication system
│ │ └── requirements.txt
│ ├── agent/ # Kubernetes agent (Go)
│ │ ├── cmd/agent/ # Agent main application
│ │ └── Dockerfile
│ ├── integrations/ # External integrations
│ │ ├── git/ # GitHub/GitLab integration
│ │ ├── slack/ # Slack notifications
│ │ ├── teams/ # Microsoft Teams integration
│ │ ├── pagerduty/ # PagerDuty integration
│ │ └── email/ # Email notifications
│ └── ui/ # Dashboard UI (served at /dashboard)
├── docs/ # Technical documentation
├── helm/ # Kubernetes Helm charts
├── docker-compose.yml # Local development setup
└── README.md # This file
Integrate PatchPulse into your CI/CD pipeline to automatically analyze PRs:
# GitHub Actions example
- name: Analyze with PatchPulse
run: |
curl -X POST $PATCHPULSE_URL/api/v1/change-events \
-H "Content-Type: application/json" \
-d @change-event.jsonValidate Kubernetes manifests before deployment:
# Analyze deployment manifests
kubectl apply --dry-run=client -f deployment.yaml | \
patchpulse analyze --source=manualTrack compliance with Kubernetes best practices:
# Get compliance report
curl http://localhost:8000/api/v1/analytics/compliancePrevent production incidents by catching risky changes:
- Missing resource limits
- Security misconfigurations
- Image tag issues
- Network policy violations
Use PatchPulse to educate teams on Kubernetes best practices:
- Real-time feedback on PRs
- Detailed explanations of guardrail violations
- Historical analytics on common mistakes
- API keys never exposed in logs or responses
- Least-privilege RBAC for agent
- Encrypted database connections
- TLS for all API communications
- Audit logging for all decisions
- Rate limiting on API endpoints
- Self-hosted - your data stays on your infrastructure
See SECURITY.md for detailed security information.
Contributions are welcome! This is a solo project, so any help is genuinely appreciated.
- Fork the repo
- Create a branch (
git checkout -b feature/your-feature) - Make your changes
- Commit (
git commit -m 'Add your feature') - Push (
git push origin feature/your-feature) - Open a Pull Request
See CONTRIBUTING.md for more details.
What I'd love help with:
- 🐛 Bug fixes (especially edge cases I haven't hit yet)
- ✨ New features (if you have ideas, open an issue first to discuss)
- 📚 Documentation (I'm not great at writing docs, so improvements are welcome)
- 🧪 Tests (more test coverage is always good)
- 🎨 UI improvements (the dashboard could definitely be prettier)
- 🔌 New integrations (want to add something? Let's talk)
This project is licensed under the PatchPulse Non-Commercial License - see the LICENSE file for details.
✅ Permitted Uses:
- Personal use
- Educational use
- Research and development
- Internal use within non-profit organizations
- Contributing to the PatchPulse project
- Forking and modifying for personal/educational purposes
❌ Prohibited Uses:
- Commercial use (selling, licensing, or providing as a service)
- Use in commercial products or services
- Reselling or redistributing for profit
- Use by for-profit companies without explicit written permission
💼 Commercial Licensing: For commercial use, please contact us to obtain a commercial license. Commercial licenses are available for:
- SaaS providers
- Enterprise deployments
- Commercial products incorporating PatchPulse
- Consulting services using PatchPulse
Contact: [email protected]
This license protects the open-source nature of PatchPulse while ensuring commercial use requires proper licensing.
Documentation: http://localhost:8000/docs (when running locally)
Website: https://patchpulse.dev
Issues: https://github.com/amarkdotdev/patchpulse/issues
Email: [email protected]
Ways to help:
- 🐛 Found a bug? Open an issue - I'll try to fix it
- 💡 Have an idea? Open a discussion or issue
- 📖 Docs unclear? Send a PR to improve them
If PatchPulse has saved you from a late-night incident or just made your life easier, consider buying me a coffee:
It's not required at all, but it's a nice way to say thanks and helps me justify spending more time on this project. Every bit helps! 🙏
- Multi-tenant support (in progress)
- Custom guardrail DSL
- Integration with more Git providers (Bitbucket, Azure DevOps)
- Additional AI provider support
- Compliance reporting (SOC2, ISO27001)
- Enhanced documentation
- Local LLM support (Ollama, LocalAI)
- Webhook support for real-time PR analysis
- Custom risk scoring algorithms
- Policy templates library
I'm a DevOps engineer based in Israel 🇮🇱, and I built PatchPulse because I was tired of preventable production incidents.
You know those moments when you're debugging at 2am and think "we should've caught this earlier"? That's what PatchPulse is for. It's the tool I wish I had when I was managing Kubernetes clusters at scale.
I built this in my spare time, iterating based on real problems I've faced. It's not perfect, but it's useful, and I'm sharing it because I think other teams might find it helpful too.
Want to chat?
- 📧 Email: [email protected]
- 🐙 GitHub: @amarkdotdev
- ☕ Buy Me a Coffee: buymeacoffee.com/aaronmark (if PatchPulse saves you from a late-night incident, consider it 😊)
This project wouldn't exist without the open source community. Special shoutout to everyone who's contributed, reported bugs, or just used PatchPulse and gave feedback.
Built with:
- FastAPI - Because Python web frameworks don't have to be slow
- PostgreSQL - Reliable and battle-tested
- Go - For the Kubernetes agent (because sometimes you need speed)
- Docker - Makes deployment actually bearable
- Kubernetes - The thing we're all trying to make safer
🔓 Open Source | 🤖 Bring Your Own LLM | 🚀 Self-Hosted
Made with ❤️ in Israel for the Kubernetes community worldwide
⭐ Star on GitHub • 📖 Documentation • ☕ Buy Me a Coffee • 🐛 Report Bug