Security (Sentinel)
Every Grit project ships with Sentinel -- a production-grade security intelligence suite that provides a Web Application Firewall, rate limiting, brute-force protection, anomaly detection, security headers, and a real-time threat dashboard. Security is not an afterthought.
What's Included
Sentinel mounts on your Gin router with a single call and provides the following out of the box:
Web Application Firewall
Detects SQL injection, XSS, path traversal, command injection, SSRF, XXE, and more
Rate Limiting
Per-IP, per-user, per-route, and global limits with sliding window strategy
Auth Shield
Brute-force protection with per-IP lockouts and credential stuffing detection
Security Headers
CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy
Anomaly Detection
Off-hours access, velocity anomalies, impossible travel, data exfiltration
IP Geolocation
Automatic geo-lookup for every request with country and city data
Threat Dashboard
Embedded React dashboard with real-time WebSocket updates at /sentinel/ui
Performance Monitoring
Per-route latency tracking with p50/p95/p99 metrics
Configuration
Sentinel is enabled by default in every Grit project. Configure it through your .env file:
# Security — Sentinel WAF, rate limiting, threat detectionSENTINEL_ENABLED=trueSENTINEL_USERNAME=adminSENTINEL_PASSWORD=sentinelSENTINEL_SECRET_KEY=change-me-in-production
| Variable | Default | Description |
|---|---|---|
| SENTINEL_ENABLED | true | Set to "false" to disable Sentinel entirely |
| SENTINEL_USERNAME | admin | Dashboard login username |
| SENTINEL_PASSWORD | sentinel | Dashboard login password |
| SENTINEL_SECRET_KEY | sentinel-secret... | Secret for dashboard JWT sessions |
How It Works
Sentinel is mounted in your routes.go Setup function, right after the global middleware (Logger, Recovery, CORS) and before any route registrations. This means every request passes through Sentinel's security middleware:
// Mount Sentinel security suiteif cfg.SentinelEnabled {sentinel.Mount(r, db, sentinel.Config{Dashboard: sentinel.DashboardConfig{Username: cfg.SentinelUsername,Password: cfg.SentinelPassword,SecretKey: cfg.SentinelSecretKey,},WAF: sentinel.WAFConfig{Enabled: true,Mode: sentinel.ModeLog,},RateLimit: sentinel.RateLimitConfig{Enabled: true,ByIP: &sentinel.Limit{Requests: 100, Window: 1 * time.Minute},ByRoute: map[string]sentinel.Limit{"/api/auth/login": {Requests: 5, Window: 15 * time.Minute},"/api/auth/register": {Requests: 3, Window: 15 * time.Minute},},},AuthShield: sentinel.AuthShieldConfig{Enabled: true,LoginRoute: "/api/auth/login",},Anomaly: sentinel.AnomalyConfig{Enabled: true,},Geo: sentinel.GeoConfig{Enabled: true,},})}
The middleware execution order is: Auth Shield (intercepts login attempts) → WAF (inspects all input vectors) → Rate Limiter (enforces request limits) → Security Headers (injects response headers) → Performance Monitor (tracks latency).
Security Dashboard
Sentinel ships with an embedded React dashboard at /sentinel/ui. Log in with the username and password from your .env file (default: admin / sentinel).
The dashboard provides:
- Threat feed -- real-time threat events via WebSocket with severity, type, and source IP
- Threat actors -- automatic profiling with risk scores, attack types, and geolocation
- Security score -- weighted score across 5 dimensions with actionable recommendations
- Analytics -- attack trends, geographic distribution, top targeted routes
- WAF rules -- view and configure rules, test payloads, add custom patterns
- Rate limits -- view active limits and live counter states
- IP management -- block/unblock IPs, view blocked list
- Audit logs -- GORM-level CREATE/UPDATE/DELETE audit trail with before/after diffs
- Performance -- per-route latency metrics (p50/p95/p99) and error rates
- Compliance reports -- generate GDPR, PCI-DSS, and SOC2 reports
The dashboard is also embedded in the admin panel under System → Security for convenience.
WAF Modes
The Web Application Firewall has two modes:
ModeLogdefaultDetects and logs threats but does not block requests. Use during development and initial deployment to identify false positives before switching to block mode.
ModeBlockproductionDetects threats and blocks malicious requests with a 403 response. Switch to this mode in production after verifying no false positives in log mode.
To switch modes, change sentinel.ModeLog to sentinel.ModeBlock in your routes.go. You can also toggle the mode at runtime from the dashboard.
The WAF detects the following attack types with configurable sensitivity per rule (off, low, medium, strict):
Rate Limiting
Grit configures sensible rate limits out of the box. You can customize them in routes.go:
RateLimit: sentinel.RateLimitConfig{Enabled: true,ByIP: &sentinel.Limit{Requests: 100, Window: 1 * time.Minute},ByRoute: map[string]sentinel.Limit{"/api/auth/login": {Requests: 5, Window: 15 * time.Minute},"/api/auth/register": {Requests: 3, Window: 15 * time.Minute},"/api/uploads": {Requests: 10, Window: 1 * time.Minute},},// Optional: per-user and global limits// ByUser: &sentinel.Limit{Requests: 200, Window: 1 * time.Minute},// Global: &sentinel.Limit{Requests: 1000, Window: 1 * time.Minute},Strategy: sentinel.SlidingWindow, // or FixedWindow, TokenBucket},
Auth Shield
The auth shield protects your login endpoint from brute-force attacks. When enabled, it automatically tracks failed login attempts per IP address and locks out attackers after too many failures.
AuthShield: sentinel.AuthShieldConfig{Enabled: true,LoginRoute: "/api/auth/login",MaxFailedAttempts: 5, // Lock after 5 failures (default)LockoutDuration: 15 * time.Minute, // 15-minute lockout (default)CredentialStuffingDetection: true, // Detect credential listsBruteForceDetection: true, // Detect brute-force patterns},
Locked-out users can be unblocked from the dashboard or via the API.
Custom WAF Rules
You can add custom WAF rules to detect application-specific attack patterns:
WAF: sentinel.WAFConfig{Enabled: true,Mode: sentinel.ModeBlock,CustomRules: []sentinel.WAFRule{{ID: "block-admin-enum",Name: "Block admin enumeration",Pattern: `(?i)/(wp-admin|phpmyadmin|administrator)`,AppliesTo: []string{"path"},Severity: sentinel.SeverityMedium,Action: "block",Enabled: true,},},ExcludeRoutes: []string{"/api/health"}, // Skip WAF for health checks},
Custom rules can also be managed at runtime from the dashboard without redeploying.
AI-Powered Analysis
If you have an AI API key configured (Claude, OpenAI, or Gemini), Sentinel can use it for intelligent threat analysis:
AI: &sentinel.AIConfig{Provider: sentinel.Claude, // or sentinel.OpenAI, sentinel.GeminiAPIKey: cfg.AIAPIKey, // Reuse your existing AI API keyDailySummary: true, // Generate daily threat summaries},
- Threat analysis -- AI evaluates individual threats and provides context
- Actor assessment -- AI profiles threat actors and predicts intent
- Daily summaries -- automated security briefings
- Natural language queries -- ask questions about your security data
- WAF recommendations -- AI suggests new rules based on attack patterns
Alerts
Sentinel can send real-time alerts when threats are detected. Configure one or more channels:
Alerts: sentinel.AlertConfig{MinSeverity: sentinel.SeverityHigh,Slack: &sentinel.SlackConfig{WebhookURL: "https://hooks.slack.com/services/...",},Email: &sentinel.EmailConfig{SMTPHost: "smtp.example.com",SMTPPort: 587,Username: "alerts@example.com",Password: "smtp-password",Recipients: []string{"security@example.com"},},Webhook: &sentinel.WebhookConfig{URL: "https://your-siem.example.com/webhook",Headers: map[string]string{"X-Token": "your-token"},},},
Production Checklist
Before deploying to production, make sure to:
Disabling Sentinel
If you don't need Sentinel, set SENTINEL_ENABLED=false in your .env file. The app will run normally without any security middleware or dashboard -- no code changes needed.