Abhishek-yadav04/Obsidian
Enterprise-Grade Web Application Firewall with GeoIP blocking, threat intelligence, JWT auth, rate limiting, and real-time analytics. Built on Coraza v3 engine.
π‘οΈ OBSIDIAN Sentinel WAF v2.2.4 Enterprise Edition
Enterprise-Grade Web Application Firewall with Advanced Security Features
Built on Coraza v3 Engine | Real-Time Protection | Zero-Trust Architecture | GeoIP Blocking | Advanced Analytics
Features β’ Quick Start β’ Architecture β’ API β’ Deployment β’ Security
π Overview
Obsidian Sentinel is an enterprise-ready Web Application Firewall that provides comprehensive protection against advanced cyber threats. It combines the battle-tested Coraza WAF engine with cutting-edge enterprise features including GeoIP blocking, advanced rate limiting, threat intelligence, webhook alerting, and sophisticated analytics.
Why Obsidian?
- π Zero-Trust Security: HMAC-SHA256 JWT authentication, RBAC, CSRF protection, and cryptographic token validation
- β‘ High Performance: Concurrent-safe design with minimal allocation on hot paths (256-shard rate limiter)
- π Real-Time Monitoring: WebSocket-based live dashboard with Chart.js visualizations and instant threat visibility
- π Advanced Threat Intelligence: Integrates with Spamhaus, Emerging Threats, Firehol, and custom feeds (2000+ threats)
- πΊοΈ GeoIP Protection: Country-based blocking with MaxMind database support and risk assessment
- π¨ Smart Alerting: Webhook integrations for Slack, Teams, Discord, PagerDuty with severity filtering
- π Enterprise Analytics: PostgreSQL integration, comprehensive audit logging, and executive reporting
- π± Modern UI: Responsive Bootstrap 5 dark theme dashboard with mobile support
- π¦ Single Binary: All assets embedded - Redis/PostgreSQL optional for enterprise features
β¨ Features
Core Security Features
| Feature | Description |
|---|---|
| 59+ Advanced WAF Rules | Protection against XSS, SQLi, RCE, LFI, RFI, SSRF, XXE, SSTI, LDAP injection |
| JWT Authentication | HMAC-SHA256 signed tokens with configurable expiration and refresh |
| Advanced RBAC | Role-based access control (Admin, Analyst, Viewer) with granular permissions |
| 256-Shard Rate Limiting | High-performance sliding window with Redis clustering support |
| Multi-Feed Threat Intel | Real-time protection from Spamhaus, Emerging Threats, Firehol (2000+ threats) |
| GeoIP Blocking | Country-based protection with MaxMind database and risk scoring |
| CSRF Protection | Token-based cross-site request forgery prevention |
| Security Headers | CSP, HSTS, X-Frame-Options, X-Content-Type-Options |
Enterprise Features
| Feature | Description |
|---|---|
| PostgreSQL Integration | Enterprise-grade data persistence and analytics |
| Redis Clustering | Distributed rate limiting and session management |
| HIBP Password Checking | Real-time password breach validation using Have I Been Pwned |
| Response Body DLP | Data Loss Prevention for sensitive information in HTTP responses |
| GraphQL Security Analyzer | Advanced GraphQL query analysis with configurable limits |
| Cache Statistics Dashboard | Real-time cache performance metrics and management |
| Rate Limit Reset Controls | Administrative controls for rate limit management |
| Glassmorphism UI | Modern dashboard with glassmorphism effects and enhanced UX |
| Password Strength Meter | Real-time password validation with visual feedback |
| Webhook Alerting | Real-time notifications to Slack, Teams, Discord, PagerDuty |
| Executive Reporting | PDF/Excel reports with charts and threat analysis |
| Comprehensive Audit | Complete security event trail with PostgreSQL storage |
| WebSocket Real-Time | Live dashboard updates without polling overhead |
| Advanced Analytics | Request patterns, geo-distribution, threat correlation |
| Multi-Tenant Support | Admin, Security Analyst, and Read-Only Viewer roles |
| Health & Metrics | Prometheus-compatible metrics and Kubernetes-ready health checks |
| Request ID Tracing | End-to-end request tracking for incident response |
Attack Categories Protected
- Cross-Site Scripting (XSS)
- SQL Injection (SQLi)
- Remote Code Execution (RCE)
- Local File Inclusion (LFI)
- Remote File Inclusion (RFI)
- Server-Side Request Forgery (SSRF)
- XML External Entity (XXE)
- Template Injection (SSTI)
- LDAP Injection
- Session Fixation
- Java/Deserialization Attacks
π Quick Start
Prerequisites
- Go 1.23+ (or TinyGo for WASM builds)
- Windows, Linux, or macOS
- Optional for Enterprise Features:
- PostgreSQL 12+ (for advanced analytics and audit logging)
- Redis 6+ (for distributed rate limiting and clustering)
- MaxMind GeoIP2 database (for country-based blocking)
Build and Run
# Clone the repository
git clone https://github.com/Abhishek-yadav04/Obsidian.git
cd obsidian
# Install dependencies
go mod tidy
# Option 1: Run directly with Go (recommended for development)
go run ./cmd/obsidian
# Option 2: Build and run executable
cd cmd/obsidian
go build -o obsidian.exe .
./obsidian.exe
# Run with custom port
go run ./cmd/obsidian -port 8082
# Run in development mode with debug logging
go run ./cmd/obsidian -port 8082 -dev
# Run with PostgreSQL and Redis (Enterprise mode)
export DATABASE_URL="postgres://user:pass@localhost/obsidian"
export REDIS_URL="redis://localhost:6379"
export OBSIDIAN_JWT_SECRET="your-very-secure-jwt-secret-here-at-least-32-chars"
go run ./cmd/obsidian -port 8082Access the Dashboard
Open your browser and navigate to: http://localhost:8082
Default Credentials (CHANGE IMMEDIATELY IN PRODUCTION):
| Role | Username | Password |
|---|---|---|
| Admin | admin |
ObsidianAdmin#2024 |
| Analyst | analyst |
ObsidianAnalyst#2024 |
| Viewer | viewer |
ObsidianViewer#2024 |
Role Permissions:
- Admin: Full access (rules, threats, users, audit logs, settings)
- Analyst: Read-only security data + report export
- Viewer: Read-only dashboard and logs
π SECURITY NOTICE:
- Default passwords are documented and MUST be changed before production
- Set
OBSIDIAN_JWT_SECRETenvironment variable (min 32 characters)- Do NOT commit
.envfiles to version control
ποΈ Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Client Request β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Security Headers Middleware β
β (CSP, X-Frame-Options, X-Content-Type-Options) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Rate Limiter Middleware β
β (Sliding Window, Per-IP Tracking) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Threat Intelligence Check β
β (Spamhaus DROP, Emerging Threats, Custom Lists) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Coraza WAF Engine β
β (55+ ModSecurity Rules) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Application Router β
β (API Handlers, Static Files) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Project Structure
obsidian/
βββ cmd/obsidian/ # Main application entry point
β βββ main.go # Server initialization and routing
β βββ ui/ # Embedded frontend assets
β βββ index.html # Main dashboard (dark theme)
β βββ login.html # Authentication page
β βββ js/app.js # Frontend application logic
β βββ css/styles.css # Enterprise dark theme styling
β βββ assets/ # Static assets (logo, icons)
βββ internal/app/ # Core application packages
β βββ alerts/ # Webhook alert management
β βββ auth/ # JWT authentication & RBAC
β βββ geoip/ # Geographic IP blocking service
β βββ logging/ # Structured logging (Zap)
β βββ metrics/ # Prometheus-compatible metrics
β βββ ratelimit/ # 256-shard rate limiter
β βββ report/ # PDF/Excel report generation
β βββ security/ # Security middleware & headers
β βββ store/ # Data persistence (PostgreSQL/memory)
β βββ threatintel/ # Threat intelligence feeds
β βββ tracing/ # Request ID tracing
βββ migrations/ # Database migration scripts
β βββ 000001_initial_schema.up.sql
β βββ 000001_initial_schema.down.sql
βββ configs/ # Configuration files
β βββ config.yaml # Default configuration
βββ testing/ # Test suites and benchmarks
βββ e2e/ # End-to-end integration tests
βββ performance/ # Load testing scenarios
βββ testdata/ # Test fixtures and data
π§ Configuration
Environment Variables
| Variable | Description | Default | Required |
|---|---|---|---|
OBSIDIAN_JWT_SECRET |
JWT signing secret (min 32 chars) | Random in dev | Yes (prod) |
OBSIDIAN_ENV |
Environment (development/production) | development | No |
OBSIDIAN_ALLOWED_ORIGINS |
Comma-separated WebSocket origins | localhost:8082 | No |
DATABASE_URL |
PostgreSQL connection string | None | Yes |
REDIS_URL |
Redis connection string | None | No |
GEOIP_DATABASE_PATH |
Path to MaxMind GeoIP2 database | None | No |
SUPABASE_URL |
Supabase project URL for OAuth | None | No (for OAuth) |
SUPABASE_KEY |
Supabase anon/public key | None | No (for OAuth) |
LOG_LEVEL |
Logging level (debug, info, warn, error) | info | No |
LOG_FORMAT |
Log format (json, console) | json | No |
OBSIDIAN_CRS_ENABLED |
Enable OWASP CRS loading | false | No |
OBSIDIAN_CRS_PATH |
Filesystem path to CRS root | None | No |
OBSIDIAN_CRS_MODE |
CRS engine mode (DetectionOnly/On) | DetectionOnly | No |
OBSIDIAN_CRS_FAIL_OPEN |
Continue startup if CRS load fails | false | No |
OBSIDIAN_WAF_CUSTOM_RULES |
Path to Obsidian custom rules file | rules/obsidian-custom.conf | No |
OWASP CRS (External Ruleset)
Obsidian loads OWASP CRS as an external ruleset at runtime. CRS files are not vendored in this repository. To enable CRS, place the official CRS files on disk and point OBSIDIAN_CRS_PATH to the CRS root that contains crs-setup.conf and the rules/ directory.
Command Line Flags
./obsidian.exe [options]
Options:
-port int Port to run the server on (default 8082)
-dev Run in development mode (relaxed security)
-log-level Override LOG_LEVEL env var
-log-format Override LOG_FORMAT env varSample .env File
# β οΈ NEVER COMMIT THIS FILE TO VERSION CONTROL
# Copy to .env and customize for your environment
# JWT Authentication (REQUIRED in production - min 32 chars)
OBSIDIAN_JWT_SECRET=your-super-secure-random-secret-minimum-32-chars
# Environment
OBSIDIAN_ENV=production
# PostgreSQL Database (REQUIRED)
DATABASE_URL=postgresql://obsidian:secure_password@localhost:5432/obsidian?sslmode=require
# Redis Cache (OPTIONAL - enables distributed rate limiting)
REDIS_URL=redis://localhost:6379/0
# For TLS: REDIS_URL=rediss://user:pass@host:port/0
# OAuth via Supabase (OPTIONAL - enables Google/GitHub login)
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your-anon-public-key
# WebSocket Origins (customize for your domain)
OBSIDIAN_ALLOWED_ORIGINS=https://your-domain.com
# GeoIP Database (OPTIONAL)
GEOIP_DATABASE_PATH=/opt/maxmind/GeoLite2-Country.mmdb
# Logging
LOG_LEVEL=info
LOG_FORMAT=json
# OWASP CRS (external ruleset)
OBSIDIAN_CRS_ENABLED=false
OBSIDIAN_CRS_PATH=/opt/owasp-crs
OBSIDIAN_CRS_MODE=DetectionOnly
OBSIDIAN_CRS_FAIL_OPEN=false
OBSIDIAN_WAF_CUSTOM_RULES=rules/obsidian-custom.confProduction Deployment Checklist
- Set
OBSIDIAN_JWT_SECRET(32+ random characters) - Set
OBSIDIAN_ENV=production - Configure PostgreSQL with SSL (
sslmode=require) - Change all default user passwords immediately
- Configure proper
OBSIDIAN_ALLOWED_ORIGINS - Set up Redis for distributed rate limiting
- Enable GeoIP blocking if needed
- Configure reverse proxy (nginx/Caddy) with TLS
- Set up log aggregation
- Configure alerting webhooks
π‘ API Reference
Authentication
POST /api/login
Authenticate and receive JWT token.
Request:
{
"username": "admin",
"password": "password"
}Response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "...",
"user": {
"id": 1,
"username": "admin",
"role": "Admin"
},
"expires_in": 900
}Protected Endpoints (Require Bearer Token)
Core Security APIs
| Endpoint | Method | Description | Required Role |
|---|---|---|---|
/api/stats |
GET | Dashboard statistics with geo data | Viewer |
/api/logs |
GET | Security event logs with pagination | Viewer |
/api/rules |
GET | WAF rules list (59 rules) | Viewer |
/api/rules/create |
POST | Create new WAF rule | Admin |
/api/rules/update |
PUT | Update existing rule | Admin |
/api/rules/delete |
DELETE | Delete rule by ID | Admin |
/api/threats |
GET | Threat intelligence data (2000+ threats) | Viewer |
/api/threats/block |
POST | Block IP address | Admin |
Enterprise Analytics APIs
| Endpoint | Method | Description | Required Role |
|---|---|---|---|
/api/metrics |
GET | System and security metrics | Viewer |
/api/geoip/lookup |
GET | GeoIP lookup for any IP | Viewer |
/api/geoip/blocked |
GET/POST/DELETE | Manage blocked countries | Admin |
/api/geoip/metrics |
GET | GeoIP service statistics | Viewer |
/api/ratelimit/blacklist |
POST/DELETE | Manage IP blacklist | Admin |
/api/ratelimit/whitelist |
POST/DELETE | Manage IP whitelist | Admin |
Alert and Integration APIs
| Endpoint | Method | Description | Required Role |
|---|---|---|---|
/api/alerts/webhooks |
GET/POST/DELETE | Manage webhook integrations | Admin |
/api/alerts/webhooks/test |
POST | Test webhook configuration | Admin |
/api/export |
GET | Export security reports (PDF/Excel) | Analyst |
/api/admin/users |
GET | User management | Admin |
/api/admin/audit |
GET | Comprehensive audit logs | Admin |
Health Check
GET /api/health
Returns comprehensive system health status.
"note": "See CI / Release section in this README for how releases are built and how to pull the official Docker image from GHCR."
---
## π§© CI / Release
Releases are performed by the repository GitHub Actions workflows. Key points:
- The CI pipeline builds and tests the project, runs linting, security scans, and produces artifacts (platform binaries).
- A separate Docker job builds multi-arch images and pushes them to GitHub Container Registry (GHCR) under `ghcr.io/<owner>/<repo>:<tag>`.
- The release job packages artifacts and creates a GitHub Release. The workflow also verifies the pushed Docker image by attempting to `docker pull` the released image during the release job.
- An SBOM (CycloneDX JSON) is generated and attached to the release artifacts.
How to pull the official release image from GHCR:
```bash
# Authenticate to GHCR (use a personal access token with appropriate scopes)
echo "${GHCR_TOKEN}" | docker login ghcr.io -u <USERNAME> --password-stdin
# Pull the image for a given tag (example: v2.2.4)
docker pull ghcr.io/<owner>/<repo>:v2.2.4If you run into problems with releases or CI, check .github/workflows/ci.yml and .github/workflows/release.yml for the exact steps executed during builds.
{
"status": "healthy",
"uptime": "2h30m15s",
"version": "2.1.0",
"edition": "Enterprise",
"name": "Obsidian Sentinel WAF",
"features": {
"waf_engine": true,
"threat_intelligence": true,
"rate_limiting": true,
"geoip_blocking": true,
"webhook_alerts": true,
"postgresql": true,
"redis": true,
"advanced_analytics": true
},
"stats": {
"total_requests": 15432,
"blocked_requests": 127,
"active_threats": 2041,
"blocked_countries": 3
}
}
---
## π Security
### JWT Token Security
- Tokens signed with HMAC-SHA256
- Configurable expiration (default: 15 minutes)
- Refresh token rotation
- Secrets stored in environment variables
- Constant-time signature comparison
- Role-based claims validation
### Advanced Rate Limiting
- 256-shard sliding window algorithm
- Redis-backed distributed limiting
- Per-IP and per-endpoint tracking
- Configurable limits:
- 200 requests/minute general
- 5 login attempts/minute
- Custom thresholds per endpoint
- Whitelist/blacklist IP management
- Geographic rate limiting
### Threat Intelligence Sources
- **Spamhaus DROP/EDROP** - 800+ malicious networks
- **Emerging Threats** - 1000+ compromised IPs
- **Firehol Level 1** - 200+ high-confidence threats
- **Custom feeds** - User-defined blocklists
- **GeoIP risk scoring** - Country-based threat assessment
- **Real-time updates** - Feeds refreshed every 4 hours
### GeoIP Security
- MaxMind GeoIP2 database integration
- Country-based blocking/allowing
- Risk score calculation
- VPN/Proxy/Tor detection
- Threat score based on geography
- Custom country rules with reasons
### Security Headers
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Content-Security-Policy: default-src 'self'; ...
---
## π¦ Deployment
### Docker (Recommended)
#### Simple Deployment
```dockerfile
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY . .
RUN cd cmd/obsidian && go build -o obsidian .
FROM alpine:latest
RUN apk --no-cache add ca-certificates tzdata
WORKDIR /app
COPY --from=builder /app/cmd/obsidian/obsidian .
EXPOSE 8082
CMD ["./obsidian", "-port", "8082"]
Docker Compose (Repository Standard)
Use the checked-in docker-compose.yml and one of these env templates:
.env.docker.examplefor local postgres + redis containers.env.external.examplefor managed/external DB + Redis
# Internal postgres + redis
cp .env.docker.example .env.docker
docker compose --env-file .env.docker up -d --build
# External managed services
cp .env.external.example .env.external
docker compose --env-file .env.external up -d --buildNotes:
- For Compose networking, use service names (
postgres,redis) in URLs, notlocalhost. .envis for localgo runworkflows; prefer dedicated env files for Docker publish/deploy.OBSIDIAN_JWT_SECRETis required and must be set per environment.
Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: obsidian-waf
namespace: security
spec:
replicas: 3
selector:
matchLabels:
app: obsidian-waf
template:
metadata:
labels:
app: obsidian-waf
spec:
containers:
- name: obsidian
image: obsidian:2.1.0
ports:
- containerPort: 8082
env:
- name: OBSIDIAN_JWT_SECRET
valueFrom:
secretKeyRef:
name: obsidian-secrets
key: jwt-secret
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: obsidian-secrets
key: database-url
- name: REDIS_URL
value: "redis://obsidian-redis:6379/0"
- name: GEOIP_DATABASE_PATH
value: "/data/GeoLite2-Country.mmdb"
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /api/health
port: 8082
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /api/health
port: 8082
initialDelaySeconds: 5
periodSeconds: 10
volumeMounts:
- name: geoip-data
mountPath: /data
volumes:
- name: geoip-data
configMap:
name: geoip-database
---
apiVersion: v1
kind: Service
metadata:
name: obsidian-waf-service
spec:
selector:
app: obsidian-waf
ports:
- protocol: TCP
port: 80
targetPort: 8082
type: LoadBalancerSystemd Service
[Unit]
Description=Obsidian Sentinel WAF
After=network.target
[Service]
Type=simple
User=obsidian
WorkingDirectory=/opt/obsidian
Environment=OBSIDIAN_JWT_SECRET=your-secret-here
ExecStart=/opt/obsidian/obsidian -port 8082
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetπ Documentation
| Document | Description |
|---|---|
| Production Audit Report | Comprehensive security audit with 100 issues and 50 features |
| Contributing Guide | How to contribute to the project |
| Security Policy | How to report vulnerabilities |
| License | Apache 2.0 License |
π§ͺ Testing
Run Tests
go test ./... -vRun with Coverage
go test ./... -cover -coverprofile=coverage.out
go tool cover -html=coverage.outTest WAF Rules
# Test XSS blocking
curl -X GET "http://localhost:8082/api/test?input=<script>alert(1)</script>"
# Test SQL injection blocking
curl -X GET "http://localhost:8082/api/test?id=1' OR '1'='1"π Monitoring
Metrics Endpoint
GET /api/metrics returns comprehensive system metrics:
{
"total_requests": 25432,
"blocked_requests": 327,
"uptime_seconds": 172800,
"memory_alloc_mb": 65,
"memory_sys_mb": 128,
"goroutines": 23,
"rate_limiter": {
"active_visitors": 15,
"blacklist_count": 5,
"whitelist_count": 10,
"rate_limited_ips": 3,
"requests_per_minute": 200,
"shards": 256,
"total_allowed": 25105,
"total_blocked": 327
},
"threat_intel": {
"total_threats": 2041,
"feeds_active": 4,
"last_update": "2026-02-01T14:30:00Z",
"blocked_today": 127,
"high_risk_count": 1205
},
"geoip": {
"blocked_countries": 3,
"total_lookups": 15432,
"cache_hits": 12890,
"cache_misses": 2542
},
"webhooks": {
"active_webhooks": 2,
"alerts_sent_today": 15,
"alerts_failed": 1
}
}WebSocket Real-Time Updates
Connect to ws://localhost:8082/api/ws?token=<jwt> for live stats updates.
π€ Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
See CONTRIBUTING.md for detailed guidelines.
π License
This project is licensed under the Apache 2.0 License - see the LICENSE file for details.
π Acknowledgments
- Coraza WAF - The core WAF engine
- OWASP CRS - Core Rule Set inspiration
- ModSecurity - SecLang rule language
π Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Security: See SECURITY.md for reporting vulnerabilities
π¨βπ» Author
Abhishek Yadav
Computer Science Student
β Star this repo if you find it helpful!
Made with β€οΈ for the cybersecurity community
First and foremost, huge thanks to Juan Pablo Tosso for starting this project, and building an amazing community around Coraza!
Today we have lots of amazing contributors, we could not have done this without you!
Made with contrib.rocks.
