Files
breakpilot-compliance/pca-platform/heuristic-service/internal/config/config.go
Benjamin Boenisch 4435e7ea0a Initial commit: breakpilot-compliance - Compliance SDK Platform
Services: Admin-Compliance, Backend-Compliance,
AI-Compliance-SDK, Consent-SDK, Developer-Portal,
PCA-Platform, DSMS

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:47:28 +01:00

152 lines
4.1 KiB
Go

package config
import (
"encoding/json"
"os"
)
// Config holds the heuristic service configuration
type Config struct {
Port string `json:"port"`
RedisURL string `json:"redis_url"`
JWTSecret string `json:"jwt_secret"`
// Heuristic thresholds
Thresholds ThresholdConfig `json:"thresholds"`
// Heuristic weights
Weights WeightConfig `json:"weights"`
// Step-up configuration
StepUp StepUpConfig `json:"step_up"`
// Tick configuration
Tick TickConfig `json:"tick"`
// Compliance settings
Compliance ComplianceConfig `json:"compliance"`
}
// ThresholdConfig defines score thresholds
type ThresholdConfig struct {
ScorePass float64 `json:"score_pass"` // Score to pass without step-up (e.g., 0.7)
ScoreChallenge float64 `json:"score_challenge"` // Score below which step-up is required (e.g., 0.4)
}
// WeightConfig defines weights for each heuristic
type WeightConfig struct {
DwellRatio float64 `json:"dwell_ratio"` // Weight for dwell time ratio
ScrollScore float64 `json:"scroll_score"` // Weight for scroll depth
PointerVariance float64 `json:"pointer_variance"` // Weight for mouse movement patterns
ClickRate float64 `json:"click_rate"` // Weight for click interactions
}
// StepUpConfig defines step-up verification methods
type StepUpConfig struct {
Methods []string `json:"methods"` // ["webauthn", "pow"]
Primary string `json:"primary"` // Preferred method
WebAuthn WebAuthnConfig `json:"webauthn"`
PoW PoWConfig `json:"pow"`
}
// WebAuthnConfig for WebAuthn step-up
type WebAuthnConfig struct {
Enabled bool `json:"enabled"`
UserVerification string `json:"userVerification"` // "preferred", "required", "discouraged"
TimeoutMs int `json:"timeout_ms"`
ChallengeEndpoint string `json:"challenge_endpoint"`
}
// PoWConfig for Proof-of-Work step-up
type PoWConfig struct {
Enabled bool `json:"enabled"`
Difficulty int `json:"difficulty"` // Number of leading zero bits required
MaxDurationMs int `json:"max_duration_ms"` // Max time for PoW computation
}
// TickConfig for periodic tick submissions
type TickConfig struct {
Endpoint string `json:"endpoint"`
IntervalMs int `json:"interval_ms"`
}
// ComplianceConfig for privacy compliance
type ComplianceConfig struct {
GDPR bool `json:"gdpr"`
AnonymizeIP bool `json:"anonymize_ip"`
NoCookies bool `json:"no_cookies"`
NoPII bool `json:"no_pii"`
}
// PathConfig for path-specific rules
type PathConfig struct {
MinScore float64 `json:"min_score"`
StepUpMethod *string `json:"step_up_method"` // nil means no step-up
}
// DefaultConfig returns a default configuration
func DefaultConfig() *Config {
return &Config{
Port: getEnv("PORT", "8085"),
RedisURL: getEnv("REDIS_URL", "redis://localhost:6379"),
JWTSecret: getEnv("JWT_SECRET", "pca-secret-change-me"),
Thresholds: ThresholdConfig{
ScorePass: 0.7,
ScoreChallenge: 0.4,
},
Weights: WeightConfig{
DwellRatio: 0.30,
ScrollScore: 0.25,
PointerVariance: 0.20,
ClickRate: 0.25,
},
StepUp: StepUpConfig{
Methods: []string{"webauthn", "pow"},
Primary: "webauthn",
WebAuthn: WebAuthnConfig{
Enabled: true,
UserVerification: "preferred",
TimeoutMs: 60000,
ChallengeEndpoint: "/pca/v1/webauthn-challenge",
},
PoW: PoWConfig{
Enabled: true,
Difficulty: 4,
MaxDurationMs: 5000,
},
},
Tick: TickConfig{
Endpoint: "/pca/v1/tick",
IntervalMs: 5000,
},
Compliance: ComplianceConfig{
GDPR: true,
AnonymizeIP: true,
NoCookies: true,
NoPII: true,
},
}
}
// LoadFromFile loads configuration from a JSON file
func LoadFromFile(path string) (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
return DefaultConfig(), nil // Return default if file not found
}
config := DefaultConfig()
if err := json.Unmarshal(data, config); err != nil {
return nil, err
}
return config, nil
}
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}