Configuration Reference
Sentinel is configured by passing a sentinel.Config struct to sentinel.Mount(). Every field has a sensible default, so you can start with an empty struct and enable features incrementally. This page documents every configuration section, its fields, default values, and usage patterns.
Zero-Value Friendly
sentinel.Config{} gives you a working setup with SQLite storage, the dashboard enabled, security headers active, and performance monitoring on. Features like WAF, rate limiting, and anomaly detection are opt-in via their Enabled field.Complete Example
Below is a fully configured Sentinel instance with every major feature enabled. In practice, you only need to set the fields relevant to your application.
1package main23import (4 "time"56 sentinel "github.com/MUKE-coder/sentinel"7 "github.com/gin-gonic/gin"8)910func main() {11 r := gin.Default()1213 sentinel.Mount(r, nil, sentinel.Config{14 Dashboard: sentinel.DashboardConfig{15 Username: "admin",16 Password: "s3cur3-p4ss!",17 SecretKey: "my-jwt-secret-change-in-production",18 },1920 Storage: sentinel.StorageConfig{21 Driver: sentinel.SQLite,22 DSN: "sentinel.db",23 RetentionDays: 90,24 MaxOpenConns: 10,25 MaxIdleConns: 5,26 },2728 WAF: sentinel.WAFConfig{29 Enabled: true,30 Mode: sentinel.ModeBlock,31 Rules: sentinel.RuleSet{32 SQLInjection: sentinel.RuleStrict,33 XSS: sentinel.RuleStrict,34 PathTraversal: sentinel.RuleStrict,35 CommandInjection: sentinel.RuleStrict,36 SSRF: sentinel.RuleMedium,37 XXE: sentinel.RuleStrict,38 LFI: sentinel.RuleStrict,39 OpenRedirect: sentinel.RuleMedium,40 },41 CustomRules: []sentinel.WAFRule{42 {43 ID: "block-admin-enum",44 Name: "Block admin enumeration",45 Pattern: `(?i)/(wp-admin|phpmyadmin|administrator)`,46 AppliesTo: []string{"path"},47 Severity: sentinel.SeverityMedium,48 Action: "block",49 Enabled: true,50 },51 },52 ExcludeRoutes: []string{"/health", "/metrics"},53 ExcludeIPs: []string{"10.0.0.0/8"},54 },5556 RateLimit: sentinel.RateLimitConfig{57 Enabled: true,58 Strategy: sentinel.SlidingWindow,59 ByIP: &sentinel.Limit{Requests: 100, Window: time.Minute},60 ByUser: &sentinel.Limit{Requests: 500, Window: time.Minute},61 Global: &sentinel.Limit{Requests: 5000, Window: time.Minute},62 ByRoute: map[string]sentinel.Limit{63 "/api/login": {Requests: 5, Window: 15 * time.Minute},64 "/api/register": {Requests: 3, Window: time.Hour},65 },66 },6768 AuthShield: sentinel.AuthShieldConfig{69 Enabled: true,70 LoginRoute: "/api/login",71 MaxFailedAttempts: 5,72 LockoutDuration: 15 * time.Minute,73 CredentialStuffingDetection: true,74 BruteForceDetection: true,75 },7677 Headers: sentinel.HeaderConfig{78 ContentSecurityPolicy: "default-src 'self'",79 StrictTransportSecurity: true,80 XFrameOptions: "DENY",81 XContentTypeOptions: true,82 ReferrerPolicy: "strict-origin-when-cross-origin",83 PermissionsPolicy: "camera=(), microphone=(), geolocation=()",84 },8586 Anomaly: sentinel.AnomalyConfig{87 Enabled: true,88 Sensitivity: sentinel.AnomalySensitivityMedium,89 LearningPeriod: 7 * 24 * time.Hour,90 Checks: []sentinel.AnomalyCheckType{91 sentinel.CheckImpossibleTravel,92 sentinel.CheckUnusualAccess,93 sentinel.CheckDataExfiltration,94 sentinel.CheckOffHoursAccess,95 sentinel.CheckVelocityAnomaly,96 },97 },9899 IPReputation: sentinel.IPReputationConfig{100 Enabled: true,101 AbuseIPDBKey: "your-abuseipdb-api-key",102 AutoBlock: true,103 MinAbuseScore: 80,104 },105106 Geo: sentinel.GeoConfig{107 Enabled: true,108 Provider: sentinel.GeoIPFree,109 },110111 Alerts: sentinel.AlertConfig{112 MinSeverity: sentinel.SeverityHigh,113 Slack: &sentinel.SlackConfig{114 WebhookURL: "https://hooks.slack.com/services/...",115 },116 Email: &sentinel.EmailConfig{117 SMTPHost: "smtp.example.com",118 SMTPPort: 587,119 Username: "alerts@example.com",120 Password: "smtp-password",121 Recipients: []string{"security@example.com"},122 },123 Webhook: &sentinel.WebhookConfig{124 URL: "https://your-siem.example.com/webhook",125 Headers: map[string]string{126 "Authorization": "Bearer your-token",127 },128 },129 },130131 AI: &sentinel.AIConfig{132 Provider: sentinel.Claude,133 APIKey: "your-anthropic-api-key",134 Model: "claude-sonnet-4-20250514",135 DailySummary: true,136 },137138 UserExtractor: func(c *gin.Context) *sentinel.UserContext {139 userID := c.GetHeader("X-User-ID")140 if userID == "" {141 return nil142 }143 return &sentinel.UserContext{144 ID: userID,145 Email: c.GetHeader("X-User-Email"),146 Role: c.GetHeader("X-User-Role"),147 }148 },149150 Performance: sentinel.PerformanceConfig{151 SlowRequestThreshold: 2 * time.Second,152 SlowQueryThreshold: 500 * time.Millisecond,153 TrackMemory: true,154 TrackGoroutines: true,155 },156 })157158 r.GET("/api/hello", func(c *gin.Context) {159 c.JSON(200, gin.H{"message": "Hello, World!"})160 })161162 r.Run(":8080")163}
Dashboard
The DashboardConfig controls the embedded React security dashboard. The dashboard is enabled by default and served under the configured prefix. It is protected by JWT-based authentication using the username and password you provide.
| Field | Type | Default | Description |
|---|---|---|---|
Enabled | *bool | true | Whether the dashboard is served. Set to false to disable entirely. |
Prefix | string | /sentinel | URL prefix for the dashboard and API routes. The UI is available at {prefix}/ui. |
Username | string | admin | Username for dashboard login. |
Password | string | sentinel | Password for dashboard login. |
SecretKey | string | sentinel-default-secret-change-me | Secret key used to sign JWT tokens for dashboard sessions. |
1Dashboard: sentinel.DashboardConfig{2 Prefix: "/admin/security",3 Username: "secops",4 Password: "change-me-in-production",5 SecretKey: "a-strong-random-secret",6}
Change Default Credentials
admin/sentinel) and secret key are intended for development only. Always set strong values in production. The SecretKey is used to sign JWT tokens — if it is compromised, attackers can forge dashboard sessions.Disabling the Dashboard
Enabled to false. Because the field is a *bool, you need to use a pointer:disabled := falseDashboard: sentinel.DashboardConfig{Enabled: &disabled,}
Storage
The StorageConfig controls how Sentinel persists security events, threat actors, rate limit counters, and other data. Sentinel ships with two built-in storage drivers and supports additional drivers.
| Field | Type | Default | Description |
|---|---|---|---|
Driver | StorageDriver | sentinel.SQLite | Storage backend. Options: sentinel.SQLite, sentinel.Memory, sentinel.Postgres, sentinel.MySQL. |
DSN | string | sentinel.db | Data source name. For SQLite, this is a file path. For Postgres/MySQL, a full connection string. |
RetentionDays | int | 90 | Number of days to retain security events before automatic cleanup. |
MaxOpenConns | int | 10 | Maximum number of open database connections. |
MaxIdleConns | int | 5 | Maximum number of idle database connections. |
Storage Drivers
| Driver | Constant | Notes |
|---|---|---|
| SQLite | sentinel.SQLite | Pure Go (no CGo). Recommended for most deployments. Data persists to a file. |
| Memory | sentinel.Memory | In-memory store. No persistence — data is lost on restart. Useful for testing. |
| Postgres | sentinel.Postgres | PostgreSQL backend for high-availability production deployments. |
| MySQL | sentinel.MySQL | MySQL/MariaDB backend. |
1// SQLite (default, recommended)2Storage: sentinel.StorageConfig{3 Driver: sentinel.SQLite,4 DSN: "sentinel.db",5 RetentionDays: 30,6}78// In-memory (for development/testing)9Storage: sentinel.StorageConfig{10 Driver: sentinel.Memory,11}1213// PostgreSQL14Storage: sentinel.StorageConfig{15 Driver: sentinel.Postgres,16 DSN: "postgres://user:pass@localhost:5432/sentinel?sslmode=disable",17 MaxOpenConns: 25,18 MaxIdleConns: 10,19}
No CGo Required
github.com/glebarez/sqlite), so you do not need CGo or any C compiler installed. This makes cross-compilation and Docker builds straightforward.WAF (Web Application Firewall)
The WAFConfig controls the built-in Web Application Firewall. When enabled, it inspects incoming requests for SQL injection, XSS, path traversal, command injection, SSRF, XXE, LFI, and open redirect attacks. It can operate in log-only mode (observe without blocking) or block mode (reject malicious requests with a 403 status).
| Field | Type | Default | Description |
|---|---|---|---|
Enabled | bool | false | Enables the WAF middleware. Must be set to true to activate. |
Mode | WAFMode | sentinel.ModeLog | How detected threats are handled. Options: sentinel.ModeLog, sentinel.ModeBlock, sentinel.ModeChallenge. |
Rules | RuleSet | All RuleStrict | Per-category sensitivity levels for built-in detection rules. |
CustomRules | []WAFRule | nil | Custom regex-based rules for application-specific patterns. |
ExcludeRoutes | []string | nil | Routes to exclude from WAF inspection (e.g., health check endpoints). |
ExcludeIPs | []string | nil | IP addresses or CIDR ranges to exclude from WAF inspection. |
WAF Modes
| Mode | Constant | Behavior |
|---|---|---|
| Log | sentinel.ModeLog | Detects and logs threats but allows the request to proceed. Good for initial rollout. |
| Block | sentinel.ModeBlock | Detects threats and rejects the request with HTTP 403. Recommended for production. |
| Challenge | sentinel.ModeChallenge | Presents a challenge to the client before allowing the request through. |
RuleSet — Per-Category Sensitivity
Each built-in detection category can have its sensitivity tuned independently. The available levels are sentinel.RuleOff, sentinel.RuleLow, sentinel.RuleMedium, and sentinel.RuleStrict.
| Field | Default | Description |
|---|---|---|
SQLInjection | RuleStrict | SQL injection detection sensitivity. |
XSS | RuleStrict | Cross-site scripting detection sensitivity. |
PathTraversal | RuleStrict | Path traversal (../../etc/passwd) detection sensitivity. |
CommandInjection | RuleStrict | OS command injection detection sensitivity. |
SSRF | RuleMedium | Server-side request forgery detection sensitivity. |
XXE | RuleStrict | XML external entity injection detection sensitivity. |
LFI | RuleStrict | Local file inclusion detection sensitivity. |
OpenRedirect | RuleMedium | Open redirect detection sensitivity. |
Custom WAF Rules
Custom rules let you add application-specific detection patterns using regular expressions. Each rule is defined as a WAFRule struct.
| Field | Type | Description |
|---|---|---|
ID | string | Unique identifier for the rule. |
Name | string | Human-readable name displayed in the dashboard. |
Pattern | string | Go-compatible regular expression to match against request data. |
AppliesTo | []string | Which parts of the request to inspect: "path", "query", "body", "headers". |
Severity | Severity | Severity level: sentinel.SeverityLow, SeverityMedium, SeverityHigh, SeverityCritical. |
Action | string | Action to take: "block" or "log". |
Enabled | bool | Whether the rule is active. |
1WAF: sentinel.WAFConfig{2 Enabled: true,3 Mode: sentinel.ModeBlock,4 Rules: sentinel.RuleSet{5 SQLInjection: sentinel.RuleStrict,6 XSS: sentinel.RuleStrict,7 PathTraversal: sentinel.RuleStrict,8 CommandInjection: sentinel.RuleStrict,9 SSRF: sentinel.RuleMedium,10 XXE: sentinel.RuleStrict,11 LFI: sentinel.RuleStrict,12 OpenRedirect: sentinel.RuleMedium,13 },14 CustomRules: []sentinel.WAFRule{15 {16 ID: "block-admin-enum",17 Name: "Block admin enumeration",18 Pattern: `(?i)/(wp-admin|phpmyadmin|administrator)`,19 AppliesTo: []string{"path"},20 Severity: sentinel.SeverityMedium,21 Action: "block",22 Enabled: true,23 },24 {25 ID: "block-sensitive-files",26 Name: "Block sensitive file access",27 Pattern: `(?i)\.(env|git|bak|sql|log)$`,28 AppliesTo: []string{"path"},29 Severity: sentinel.SeverityHigh,30 Action: "block",31 Enabled: true,32 },33 },34 ExcludeRoutes: []string{"/health", "/readiness"},35 ExcludeIPs: []string{"127.0.0.1", "10.0.0.0/8"},36}
Recommended Rollout Strategy
sentinel.ModeLog in production to observe what the WAF detects without blocking real traffic. Review the dashboard for false positives, tune rule sensitivities, then switch to sentinel.ModeBlock when confident.Rate Limiting
The RateLimitConfig enables multi-dimensional rate limiting. You can set limits per IP, per authenticated user, per route, and globally. All dimensions are enforced independently — a request must pass all applicable limits.
| Field | Type | Default | Description |
|---|---|---|---|
Enabled | bool | false | Enables the rate limiting middleware. |
Strategy | RateLimitStrategy | sentinel.SlidingWindow | Algorithm used for counting. Options: sentinel.SlidingWindow, sentinel.FixedWindow, sentinel.TokenBucket. |
ByIP | *Limit | nil | Per-IP rate limit. Each unique client IP gets its own counter. |
ByUser | *Limit | nil | Per-user rate limit. Requires a UserIDExtractor or UserExtractor. |
ByRoute | map[string]Limit | nil | Per-route rate limits. Keys are route patterns (e.g., /api/login). |
Global | *Limit | nil | Global rate limit applied across all requests regardless of source. |
UserIDExtractor | func(*gin.Context) string | nil | Function to extract a user ID from the request for per-user limiting. |
The Limit Struct
Each limit is defined by a number of allowed requests within a time window.
| Field | Type | Description |
|---|---|---|
Requests | int | Maximum number of requests allowed within the window. |
Window | time.Duration | Time window for the limit (e.g., time.Minute, 15 * time.Minute). |
Rate Limit Strategies
| Strategy | Constant | Description |
|---|---|---|
| Sliding Window | sentinel.SlidingWindow | Default. Provides smooth rate limiting without burst spikes at window boundaries. |
| Fixed Window | sentinel.FixedWindow | Simple fixed time windows. Slightly less accurate but lower memory overhead. |
| Token Bucket | sentinel.TokenBucket | Allows short bursts while maintaining an average rate over time. |
1RateLimit: sentinel.RateLimitConfig{2 Enabled: true,3 Strategy: sentinel.SlidingWindow,45 // 100 requests per minute per IP6 ByIP: &sentinel.Limit{Requests: 100, Window: time.Minute},78 // 500 requests per minute per authenticated user9 ByUser: &sentinel.Limit{Requests: 500, Window: time.Minute},1011 // 5000 requests per minute globally12 Global: &sentinel.Limit{Requests: 5000, Window: time.Minute},1314 // Strict limits on sensitive routes15 ByRoute: map[string]sentinel.Limit{16 "/api/login": {Requests: 5, Window: 15 * time.Minute},17 "/api/register": {Requests: 3, Window: time.Hour},18 "/api/password-reset": {Requests: 3, Window: time.Hour},19 },2021 // Extract user ID from your auth system22 UserIDExtractor: func(c *gin.Context) string {23 return c.GetHeader("X-User-ID")24 },25}
Rate Limit Headers
X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. When a limit is exceeded, the client receives a 429 Too Many Requests response.Auth Shield
The AuthShieldConfig protects authentication endpoints from brute-force attacks and credential stuffing. When enabled, it monitors the configured login route for failed authentication attempts and automatically locks out offending IPs.
| Field | Type | Default | Description |
|---|---|---|---|
Enabled | bool | false | Enables the Auth Shield middleware. |
LoginRoute | string | "" | The route path for your login endpoint (e.g., /api/login). |
MaxFailedAttempts | int | 5 | Number of failed login attempts before lockout is triggered. |
LockoutDuration | time.Duration | 15 * time.Minute | How long an IP is locked out after exceeding MaxFailedAttempts. |
CredentialStuffingDetection | bool | false | Detects credential stuffing patterns (many different usernames from the same IP). |
BruteForceDetection | bool | false | Detects brute force patterns (many password attempts for the same username). |
1AuthShield: sentinel.AuthShieldConfig{2 Enabled: true,3 LoginRoute: "/api/login",4 MaxFailedAttempts: 5,5 LockoutDuration: 15 * time.Minute,6 CredentialStuffingDetection: true,7 BruteForceDetection: true,8}
LoginRoute Must Match Exactly
LoginRoute must match the exact path of your login handler. Sentinel monitors this route for non-2xx responses to count failed login attempts. If the route does not match, Auth Shield will not detect failures.Security Headers
The HeaderConfig controls automatic injection of security headers into every response. Security headers are enabled by default. These headers protect against clickjacking, MIME sniffing, XSS, and other client-side attacks.
| Field | Type | Default | Description |
|---|---|---|---|
Enabled | *bool | true | Whether security headers are injected. Use a *bool to explicitly disable. |
ContentSecurityPolicy | string | "" (not set) | Value for the Content-Security-Policy header. Left empty by default because CSP is application-specific. |
StrictTransportSecurity | bool | false | When true, sets Strict-Transport-Security: max-age=31536000; includeSubDomains. |
XFrameOptions | string | DENY | Value for the X-Frame-Options header. Common values: DENY, SAMEORIGIN. |
XContentTypeOptions | bool | true | When true, sets X-Content-Type-Options: nosniff. |
ReferrerPolicy | string | strict-origin-when-cross-origin | Value for the Referrer-Policy header. |
PermissionsPolicy | string | "" (not set) | Value for the Permissions-Policy header. Controls browser feature access. |
1Headers: sentinel.HeaderConfig{2 ContentSecurityPolicy: "default-src 'self'; script-src 'self' 'unsafe-inline'",3 StrictTransportSecurity: true,4 XFrameOptions: "DENY",5 XContentTypeOptions: true,6 ReferrerPolicy: "strict-origin-when-cross-origin",7 PermissionsPolicy: "camera=(), microphone=(), geolocation=()",8}
HSTS Warning
StrictTransportSecurity if your application is served exclusively over HTTPS. Once a browser receives an HSTS header, it will refuse to connect over plain HTTP for the specified duration.Anomaly Detection
The AnomalyConfig enables behavioral anomaly detection. Sentinel learns normal traffic patterns during a configurable learning period and then flags deviations such as impossible travel, unusual access patterns, and data exfiltration attempts.
| Field | Type | Default | Description |
|---|---|---|---|
Enabled | bool | false | Enables the anomaly detection engine. |
Sensitivity | AnomalySensitivity | sentinel.AnomalySensitivityMedium | Detection sensitivity. Options: sentinel.AnomalySensitivityLow, AnomalySensitivityMedium, AnomalySensitivityHigh. |
LearningPeriod | time.Duration | 7 * 24 * time.Hour (7 days) | Duration of the initial learning phase during which Sentinel builds baseline traffic patterns. |
Checks | []AnomalyCheckType | nil (all checks) | Which anomaly checks to run. When nil, all checks are enabled. |
Anomaly Check Types
| Check | Constant | Description |
|---|---|---|
| Impossible Travel | sentinel.CheckImpossibleTravel | Detects logins from geographically distant locations within impossibly short timeframes. |
| Unusual Access | sentinel.CheckUnusualAccess | Flags access to endpoints not typically visited by a given user or IP. |
| Data Exfiltration | sentinel.CheckDataExfiltration | Detects abnormally large data transfers or rapid sequential data access. |
| Off-Hours Access | sentinel.CheckOffHoursAccess | Flags access outside of normal business hours for a given user profile. |
| Velocity Anomaly | sentinel.CheckVelocityAnomaly | Detects sudden spikes in request velocity from a single source. |
| Credential Stuffing | sentinel.CheckCredentialStuffing | Identifies patterns consistent with credential stuffing attacks on auth endpoints. |
1Anomaly: sentinel.AnomalyConfig{2 Enabled: true,3 Sensitivity: sentinel.AnomalySensitivityMedium,4 LearningPeriod: 7 * 24 * time.Hour,5 Checks: []sentinel.AnomalyCheckType{6 sentinel.CheckImpossibleTravel,7 sentinel.CheckUnusualAccess,8 sentinel.CheckDataExfiltration,9 sentinel.CheckVelocityAnomaly,10 },11}
Learning Period
IP Reputation
The IPReputationConfig integrates with the AbuseIPDB API to check the reputation score of incoming IP addresses. Known malicious IPs can be automatically blocked.
| Field | Type | Default | Description |
|---|---|---|---|
Enabled | bool | false | Enables IP reputation checking. |
AbuseIPDBKey | string | "" | Your AbuseIPDB API key. Required when Enabled is true. |
AutoBlock | bool | false | Automatically add IPs exceeding MinAbuseScore to the blocklist. |
MinAbuseScore | int | 80 | Minimum AbuseIPDB confidence score (0-100) to consider an IP malicious. |
1IPReputation: sentinel.IPReputationConfig{2 Enabled: true,3 AbuseIPDBKey: os.Getenv("ABUSEIPDB_API_KEY"),4 AutoBlock: true,5 MinAbuseScore: 80,6}
API Rate Limits
MinAbuseScore threshold.Geolocation
The GeoConfig enables IP geolocation for enriching security events with country, city, and coordinate data. This powers the dashboard map view and the impossible travel anomaly check.
| Field | Type | Default | Description |
|---|---|---|---|
Enabled | bool | false | Enables IP geolocation lookups. |
Provider | GeoProvider | sentinel.GeoIPFree | Geolocation provider. Options: sentinel.GeoIPFree (GeoLite2), sentinel.GeoIPPaid (GeoIP2). |
1Geo: sentinel.GeoConfig{2 Enabled: true,3 Provider: sentinel.GeoIPFree,4}
Alerts
The AlertConfig configures real-time alerting when security events exceed a severity threshold. Sentinel supports three alert channels: Slack, email, and generic webhooks. You can enable one or more channels simultaneously.
| Field | Type | Default | Description |
|---|---|---|---|
MinSeverity | Severity | sentinel.SeverityHigh | Minimum severity level to trigger alerts. Options: SeverityLow, SeverityMedium, SeverityHigh, SeverityCritical. |
Slack | *SlackConfig | nil | Slack webhook configuration. Set to enable Slack alerts. |
Email | *EmailConfig | nil | Email SMTP configuration. Set to enable email alerts. |
Webhook | *WebhookConfig | nil | Generic webhook configuration. Set to enable webhook alerts. |
Slack Alerts
| Field | Type | Description |
|---|---|---|
WebhookURL | string | The Slack incoming webhook URL. |
Email Alerts
| Field | Type | Description |
|---|---|---|
SMTPHost | string | SMTP server hostname. |
SMTPPort | int | SMTP server port (typically 587 for TLS, 465 for SSL). |
Username | string | SMTP authentication username. |
Password | string | SMTP authentication password. |
Recipients | []string | List of email addresses to receive alerts. |
Webhook Alerts
| Field | Type | Description |
|---|---|---|
URL | string | The webhook endpoint URL. Sentinel sends a JSON POST request. |
Headers | map[string]string | Custom HTTP headers to include in webhook requests (e.g., for authentication). |
1Alerts: sentinel.AlertConfig{2 MinSeverity: sentinel.SeverityHigh,34 // Slack alerts5 Slack: &sentinel.SlackConfig{6 WebhookURL: "https://hooks.slack.com/services/T00/B00/xxx",7 },89 // Email alerts10 Email: &sentinel.EmailConfig{11 SMTPHost: "smtp.example.com",12 SMTPPort: 587,13 Username: "alerts@example.com",14 Password: "smtp-password",15 Recipients: []string{16 "security-team@example.com",17 "oncall@example.com",18 },19 },2021 // Webhook alerts (e.g., to a SIEM)22 Webhook: &sentinel.WebhookConfig{23 URL: "https://siem.example.com/api/ingest",24 Headers: map[string]string{25 "Authorization": "Bearer your-api-token",26 "X-Source": "sentinel",27 },28 },29}
Multiple Alert Channels
MinSeverity threshold, it is dispatched to all configured channels concurrently.AI Analysis
The AIConfig enables AI-powered security analysis. When configured, Sentinel uses large language models to analyze threat patterns, generate daily security summaries, and provide natural-language insights in the dashboard. This is an optional feature — it requires an API key from one of the supported providers.
| Field | Type | Default | Description |
|---|---|---|---|
Provider | AIProvider | (none) | AI provider. Options: sentinel.Claude, sentinel.OpenAI, sentinel.Gemini. |
APIKey | string | "" | API key for the selected provider. |
Model | string | (provider default) | Optional model override. If empty, Sentinel uses the provider's recommended model. |
DailySummary | bool | false | When true, generates a daily AI-powered security summary. |
Supported Providers
| Provider | Constant | Default Model |
|---|---|---|
| Anthropic Claude | sentinel.Claude | Claude Sonnet |
| OpenAI | sentinel.OpenAI | GPT-4o |
| Google Gemini | sentinel.Gemini | Gemini Pro |
1// Using Anthropic Claude2AI: &sentinel.AIConfig{3 Provider: sentinel.Claude,4 APIKey: os.Getenv("ANTHROPIC_API_KEY"),5 DailySummary: true,6}78// Using OpenAI9AI: &sentinel.AIConfig{10 Provider: sentinel.OpenAI,11 APIKey: os.Getenv("OPENAI_API_KEY"),12 Model: "gpt-4o",13}1415// Using Google Gemini16AI: &sentinel.AIConfig{17 Provider: sentinel.Gemini,18 APIKey: os.Getenv("GEMINI_API_KEY"),19}
AI is Optional
AI field is a pointer (*AIConfig). When left as nil, no AI provider is initialized and no API calls are made. The dashboard AI analysis tab will show a message indicating that AI is not configured.User Extractor
The UserExtractor is a function that extracts authenticated user context from each incoming request. Sentinel uses this information for per-user rate limiting, user-level threat profiling, and audit logging. Return nil for unauthenticated requests.
| Field | Type | Default | Description |
|---|---|---|---|
UserExtractor | func(*gin.Context) *UserContext | nil | Function to extract user information from a request. Return nil if no user is authenticated. |
UserContext Struct
| Field | Type | Description |
|---|---|---|
ID | string | Unique user identifier. |
Email | string | User email address (used in alerts and dashboard display). |
Role | string | User role (e.g., "admin", "user"). Used for access pattern analysis. |
1// Extract user from JWT claims set by your auth middleware2UserExtractor: func(c *gin.Context) *sentinel.UserContext {3 // Option 1: From headers (proxy/gateway sets these)4 userID := c.GetHeader("X-User-ID")5 if userID == "" {6 return nil // Unauthenticated request7 }8 return &sentinel.UserContext{9 ID: userID,10 Email: c.GetHeader("X-User-Email"),11 Role: c.GetHeader("X-User-Role"),12 }13}1415// Option 2: From Gin context (your auth middleware sets these)16UserExtractor: func(c *gin.Context) *sentinel.UserContext {17 userID, exists := c.Get("userID")18 if !exists {19 return nil20 }21 return &sentinel.UserContext{22 ID: userID.(string),23 Email: c.GetString("userEmail"),24 Role: c.GetString("userRole"),25 }26}
UserExtractor vs UserIDExtractor
Config.UserExtractor provides full user context (ID, email, role) for threat profiling and dashboard display. RateLimitConfig.UserIDExtractor is a simpler function that returns only a user ID string for rate limiting. If you set UserExtractor, Sentinel can derive the user ID from it automatically. You only need UserIDExtractor if you want rate limiting to use a different identifier.Performance Monitoring
The PerformanceConfig controls request performance tracking and system resource monitoring. Performance monitoring is enabled by default. Sentinel records request durations, flags slow requests, and optionally tracks memory usage and goroutine counts.
| Field | Type | Default | Description |
|---|---|---|---|
Enabled | *bool | true | Whether performance monitoring is active. Use a *bool to explicitly disable. |
SlowRequestThreshold | time.Duration | 2 * time.Second | Requests exceeding this duration are flagged as slow in the dashboard. |
SlowQueryThreshold | time.Duration | 500 * time.Millisecond | Database queries exceeding this duration are flagged as slow (used with the GORM plugin). |
TrackMemory | bool | false | Track Go runtime memory statistics and expose them in the dashboard. |
TrackGoroutines | bool | false | Track the number of active goroutines and expose in the dashboard. |
1Performance: sentinel.PerformanceConfig{2 SlowRequestThreshold: 1 * time.Second,3 SlowQueryThreshold: 200 * time.Millisecond,4 TrackMemory: true,5 TrackGoroutines: true,6}
Defaults (Zero Config)
When you pass an empty sentinel.Config{}, Sentinel applies the following defaults via the ApplyDefaults() method. This table summarizes the effective configuration with zero user-provided values.
| Section | Field | Default Value |
|---|---|---|
| Dashboard | Enabled | true |
| Dashboard | Prefix | /sentinel |
| Dashboard | Username | admin |
| Dashboard | Password | sentinel |
| Dashboard | SecretKey | sentinel-default-secret-change-me |
| Storage | Driver | sentinel.SQLite |
| Storage | DSN | sentinel.db |
| Storage | RetentionDays | 90 |
| Storage | MaxOpenConns | 10 |
| Storage | MaxIdleConns | 5 |
| WAF | Enabled | false |
| WAF | Mode | sentinel.ModeLog |
| WAF Rules | SQLInjection | sentinel.RuleStrict |
| WAF Rules | XSS | sentinel.RuleStrict |
| WAF Rules | PathTraversal | sentinel.RuleStrict |
| WAF Rules | CommandInjection | sentinel.RuleStrict |
| WAF Rules | SSRF | sentinel.RuleMedium |
| WAF Rules | XXE | sentinel.RuleStrict |
| WAF Rules | LFI | sentinel.RuleStrict |
| WAF Rules | OpenRedirect | sentinel.RuleMedium |
| Rate Limit | Enabled | false |
| Rate Limit | Strategy | sentinel.SlidingWindow |
| Auth Shield | Enabled | false |
| Auth Shield | MaxFailedAttempts | 5 |
| Auth Shield | LockoutDuration | 15 * time.Minute |
| Headers | Enabled | true |
| Headers | XFrameOptions | DENY |
| Headers | XContentTypeOptions | true (nosniff) |
| Headers | ReferrerPolicy | strict-origin-when-cross-origin |
| Anomaly | Enabled | false |
| Anomaly | Sensitivity | sentinel.AnomalySensitivityMedium |
| Anomaly | LearningPeriod | 7 * 24 * time.Hour |
| IP Reputation | Enabled | false |
| IP Reputation | MinAbuseScore | 80 |
| Geo | Enabled | false |
| Geo | Provider | sentinel.GeoIPFree |
| Alerts | MinSeverity | sentinel.SeverityHigh |
| AI | (entire section) | nil (disabled) |
| Performance | Enabled | true |
| Performance | SlowRequestThreshold | 2 * time.Second |
| Performance | SlowQueryThreshold | 500 * time.Millisecond |
1// Zero config — all defaults applied automatically2r := gin.Default()3sentinel.Mount(r, nil, sentinel.Config{})45// This is equivalent to:6sentinel.Mount(r, nil, sentinel.Config{7 Dashboard: sentinel.DashboardConfig{8 // Enabled: true (default)9 // Prefix: "/sentinel"10 // Username: "admin"11 // Password: "sentinel"12 },13 Storage: sentinel.StorageConfig{14 // Driver: sentinel.SQLite15 // DSN: "sentinel.db"16 // RetentionDays: 9017 },18 // WAF: disabled19 // RateLimit: disabled20 // AuthShield: disabled21 // Headers: enabled with safe defaults22 // Anomaly: disabled23 // Performance: enabled24})
Production Checklist
- Change the dashboard
Username,Password, andSecretKey - Enable the WAF with
ModeBlock - Set up rate limiting with appropriate thresholds for your traffic
- Configure at least one alert channel (Slack, email, or webhook)
- Use
sentinel.SQLiteorsentinel.Postgresfor persistent storage - Set
StrictTransportSecurity: trueif serving over HTTPS
Environment Variables Pattern
While Sentinel does not read environment variables directly, a common pattern is to read them yourself and pass them into the config struct. This keeps secrets out of your source code.
1import "os"23config := sentinel.Config{4 Dashboard: sentinel.DashboardConfig{5 Username: os.Getenv("SENTINEL_USERNAME"),6 Password: os.Getenv("SENTINEL_PASSWORD"),7 SecretKey: os.Getenv("SENTINEL_SECRET_KEY"),8 },9 Storage: sentinel.StorageConfig{10 Driver: sentinel.SQLite,11 DSN: os.Getenv("SENTINEL_DB_PATH"),12 },13 AI: &sentinel.AIConfig{14 Provider: sentinel.Claude,15 APIKey: os.Getenv("ANTHROPIC_API_KEY"),16 },17 Alerts: sentinel.AlertConfig{18 Slack: &sentinel.SlackConfig{19 WebhookURL: os.Getenv("SLACK_WEBHOOK_URL"),20 },21 },22 IPReputation: sentinel.IPReputationConfig{23 Enabled: os.Getenv("ABUSEIPDB_API_KEY") != "",24 AbuseIPDBKey: os.Getenv("ABUSEIPDB_API_KEY"),25 },26}
Never Hardcode Secrets
Next Steps
- WAF Deep Dive — Advanced WAF configuration, custom rules, and tuning
- Rate Limiting — Strategies, per-route limits, and response headers
- Auth Shield — Brute-force and credential stuffing protection
- Anomaly Detection — Behavioral analysis and learning periods
- Alerting — Slack, email, and webhook integration
- AI Analysis — Claude, OpenAI, and Gemini integration
- Dashboard — Explore the 13-page security dashboard