Some checks are pending
Go Benchmark / Performance Regression Check (push) Waiting to run
Cerberus Integration / Cerberus Security Stack Integration (push) Waiting to run
Upload Coverage to Codecov / Backend Codecov Upload (push) Waiting to run
Upload Coverage to Codecov / Frontend Codecov Upload (push) Waiting to run
CodeQL - Analyze / CodeQL analysis (go) (push) Waiting to run
CodeQL - Analyze / CodeQL analysis (javascript-typescript) (push) Waiting to run
CrowdSec Integration / CrowdSec Bouncer Integration (push) Waiting to run
Docker Build, Publish & Test / build-and-push (push) Waiting to run
Docker Build, Publish & Test / Security Scan PR Image (push) Blocked by required conditions
Quality Checks / Auth Route Protection Contract (push) Waiting to run
Quality Checks / Codecov Trigger/Comment Parity Guard (push) Waiting to run
Quality Checks / Backend (Go) (push) Waiting to run
Quality Checks / Frontend (React) (push) Waiting to run
Rate Limit integration / Rate Limiting Integration (push) Waiting to run
Security Scan (PR) / Trivy Binary Scan (push) Waiting to run
Supply Chain Verification (PR) / Verify Supply Chain (push) Waiting to run
WAF integration / Coraza WAF Integration (push) Waiting to run
203 lines
6.2 KiB
Markdown
Executable File
203 lines
6.2 KiB
Markdown
Executable File
# Security Configuration Priority System
|
|
|
|
## Overview
|
|
|
|
The Charon security configuration system uses a three-tier priority chain to determine the effective security settings. This allows for flexible configuration management across different deployment scenarios.
|
|
|
|
## Priority Chain
|
|
|
|
1. **Settings Table** (Highest Priority)
|
|
- Runtime overrides stored in the `settings` database table
|
|
- Used for feature flags and quick toggles
|
|
- Can enable/disable individual security modules without full config changes
|
|
- Takes precedence over all other sources
|
|
|
|
2. **SecurityConfig Database Record** (Middle Priority)
|
|
- Persistent configuration stored in the `security_configs` table
|
|
- Contains comprehensive security settings including admin whitelists, rate limits, etc.
|
|
- Overrides static configuration file settings
|
|
- Used for user-managed security configuration
|
|
|
|
3. **Static Configuration File** (Lowest Priority)
|
|
- Default values from `config/config.yaml` or environment variables
|
|
- Fallback when no database overrides exist
|
|
- Used for initial setup and defaults
|
|
|
|
## How It Works
|
|
|
|
When the `/api/v1/security/status` endpoint is called, the system:
|
|
|
|
1. Starts with static config values
|
|
2. Checks for SecurityConfig DB record and overrides static values if present
|
|
3. Checks for Settings table entries and overrides both static and DB values if present
|
|
4. Computes effective enabled state based on final values
|
|
|
|
## Supported Settings Table Keys
|
|
|
|
### Cerberus (Master Switch)
|
|
|
|
- `feature.cerberus.enabled` - "true"/"false" - Enables/disables all security features
|
|
|
|
### WAF (Web Application Firewall)
|
|
|
|
- `security.waf.enabled` - "true"/"false" - Overrides WAF mode
|
|
|
|
### Rate Limiting
|
|
|
|
- `security.rate_limit.enabled` - "true"/"false" - Overrides rate limit mode
|
|
|
|
### CrowdSec
|
|
|
|
- `security.crowdsec.enabled` - "true"/"false" - Sets CrowdSec to local/disabled
|
|
- `security.crowdsec.mode` - "local"/"disabled" - Direct mode override
|
|
|
|
### ACL (Access Control Lists)
|
|
|
|
- `security.acl.enabled` - "true"/"false" - Overrides ACL mode
|
|
|
|
## Examples
|
|
|
|
### Example 1: Settings Override SecurityConfig
|
|
|
|
```go
|
|
// Static Config
|
|
config.SecurityConfig{
|
|
CerberusEnabled: true,
|
|
WAFMode: "disabled",
|
|
}
|
|
|
|
// SecurityConfig DB
|
|
SecurityConfig{
|
|
Name: "default",
|
|
Enabled: true,
|
|
WAFMode: "enabled", // Tries to enable WAF
|
|
}
|
|
|
|
// Settings Table
|
|
Setting{Key: "security.waf.enabled", Value: "false"}
|
|
|
|
// Result: WAF is DISABLED (Settings table wins)
|
|
```
|
|
|
|
### Example 2: SecurityConfig Override Static
|
|
|
|
```go
|
|
// Static Config
|
|
config.SecurityConfig{
|
|
CerberusEnabled: true,
|
|
RateLimitMode: "disabled",
|
|
}
|
|
|
|
// SecurityConfig DB
|
|
SecurityConfig{
|
|
Name: "default",
|
|
Enabled: true,
|
|
RateLimitMode: "enabled", // Overrides static
|
|
}
|
|
|
|
// Settings Table
|
|
// (no settings for rate_limit)
|
|
|
|
// Result: Rate Limit is ENABLED (SecurityConfig DB wins)
|
|
```
|
|
|
|
### Example 3: Static Config Fallback
|
|
|
|
```go
|
|
// Static Config
|
|
config.SecurityConfig{
|
|
CerberusEnabled: true,
|
|
CrowdSecMode: "local",
|
|
}
|
|
|
|
// SecurityConfig DB
|
|
// (no record found)
|
|
|
|
// Settings Table
|
|
// (no settings)
|
|
|
|
// Result: CrowdSec is LOCAL (Static config wins)
|
|
```
|
|
|
|
## Important Notes
|
|
|
|
1. **Cerberus Master Switch**: All security features require Cerberus to be enabled. If Cerberus is disabled at any priority level, all features are disabled regardless of their individual settings.
|
|
|
|
2. **Mode Mapping**: Invalid CrowdSec modes are mapped to "disabled" for safety.
|
|
|
|
3. **Database Priority**: SecurityConfig DB record must have `name = "default"` to be recognized.
|
|
|
|
4. **Backward Compatibility**: The system maintains backward compatibility with the older `RateLimitEnable` boolean field by mapping it to `RateLimitMode`.
|
|
|
|
## Testing
|
|
|
|
Comprehensive unit tests verify the priority chain:
|
|
|
|
- `TestSecurityHandler_Priority_SettingsOverSecurityConfig` - Tests all three priority levels
|
|
- `TestSecurityHandler_Priority_AllModules` - Tests all security modules together
|
|
- `TestSecurityHandler_GetStatus_RespectsSettingsTable` - Tests Settings table overrides
|
|
- `TestSecurityHandler_ACL_DBOverride` - Tests ACL specific overrides
|
|
- `TestSecurityHandler_CrowdSec_Mode_DBOverride` - Tests CrowdSec mode overrides
|
|
|
|
## Implementation Details
|
|
|
|
The priority logic is implemented in [security_handler.go](backend/internal/api/handlers/security_handler.go#L55-L170):
|
|
|
|
```go
|
|
// GetStatus returns the current status of all security services.
|
|
// Priority chain:
|
|
// 1. Settings table (highest - runtime overrides)
|
|
// 2. SecurityConfig DB record (middle - user configuration)
|
|
// 3. Static config (lowest - defaults)
|
|
func (h *SecurityHandler) GetStatus(c *gin.Context) {
|
|
// Start with static config defaults
|
|
enabled := h.cfg.CerberusEnabled
|
|
wafMode := h.cfg.WAFMode
|
|
// ... other fields
|
|
|
|
// Override with database SecurityConfig if present (priority 2)
|
|
if h.db != nil {
|
|
var sc models.SecurityConfig
|
|
if err := h.db.Where("name = ?", "default").First(&sc).Error; err == nil {
|
|
enabled = sc.Enabled
|
|
if sc.WAFMode != "" {
|
|
wafMode = sc.WAFMode
|
|
}
|
|
// ... other overrides
|
|
}
|
|
|
|
// Check runtime setting overrides from settings table (priority 1 - highest)
|
|
var setting struct{ Value string }
|
|
if err := h.db.Raw("SELECT value FROM settings WHERE key = ? LIMIT 1", "security.waf.enabled").Scan(&setting).Error; err == nil && setting.Value != "" {
|
|
if strings.EqualFold(setting.Value, "true") {
|
|
wafMode = "enabled"
|
|
} else {
|
|
wafMode = "disabled"
|
|
}
|
|
}
|
|
// ... other setting checks
|
|
}
|
|
// ... compute effective state and return
|
|
}
|
|
```
|
|
|
|
## QA Verification
|
|
|
|
All previously failing tests now pass:
|
|
|
|
- ✅ `TestCertificateHandler_Delete_NotificationRateLimiting`
|
|
- ✅ `TestSecurityHandler_ACL_DBOverride`
|
|
- ✅ `TestSecurityHandler_CrowdSec_Mode_DBOverride`
|
|
- ✅ `TestSecurityHandler_GetStatus_RespectsSettingsTable` (all 6 subtests)
|
|
- ✅ `TestSecurityHandler_GetStatus_WAFModeFromSettings`
|
|
- ✅ `TestSecurityHandler_GetStatus_RateLimitModeFromSettings`
|
|
|
|
## Migration Notes
|
|
|
|
For existing deployments:
|
|
|
|
1. No database migration required - Settings table already exists
|
|
2. SecurityConfig records work as before
|
|
3. New Settings table overrides are optional
|
|
4. System remains backward compatible with all existing configurations
|