diff --git a/cmd/watchdog/root.go b/cmd/watchdog/root.go index 3e3314c..1a4521b 100644 --- a/cmd/watchdog/root.go +++ b/cmd/watchdog/root.go @@ -90,9 +90,15 @@ func Run(cfg *config.Config) error { ) } - // Add rate limiting to metrics endpoint (30 requests per minute) - metricsRateLimiter := ratelimit.NewTokenBucket(30, 30, time.Minute) - metricsHandler = rateLimitMiddleware(metricsHandler, metricsRateLimiter) + // Add rate limiting to metrics endpoint + if cfg.Limits.MaxMetricsPerMinute > 0 { + metricsRateLimiter := ratelimit.NewTokenBucket( + cfg.Limits.MaxMetricsPerMinute, + cfg.Limits.MaxMetricsPerMinute, + time.Minute, + ) + metricsHandler = rateLimitMiddleware(metricsHandler, metricsRateLimiter) + } mux.Handle(cfg.Server.MetricsPath, metricsHandler) diff --git a/internal/config/config.go b/internal/config/config.go index 595306e..158b58f 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -45,11 +45,12 @@ type PathConfig struct { // Cardinality limits type LimitsConfig struct { - MaxPaths int `yaml:"max_paths"` - MaxEventsPerMinute int `yaml:"max_events_per_minute"` - MaxSources int `yaml:"max_sources"` - MaxCustomEvents int `yaml:"max_custom_events"` - DeviceBreakpoints DeviceBreaks `yaml:"device_breakpoints"` + MaxPaths int `yaml:"max_paths"` + MaxEventsPerMinute int `yaml:"max_events_per_minute"` + MaxSources int `yaml:"max_sources"` + MaxCustomEvents int `yaml:"max_custom_events"` + DeviceBreakpoints DeviceBreaks `yaml:"device_breakpoints"` + MaxMetricsPerMinute int `yaml:"max_metrics_per_minute"` // rate limit for metrics endpoint } // Device classification breakpoints @@ -72,10 +73,11 @@ type CORSConfig struct { } // Authentication for metrics endpoint +// Password can be set via environment variable: WATCHDOG_SECURITY_METRICS_AUTH_PASSWORD type AuthConfig struct { Enabled bool `yaml:"enabled"` Username string `yaml:"username"` - Password string `yaml:"password"` + Password string `yaml:"password"` // can use env var WATCHDOG_SECURITY_METRICS_AUTH_PASSWORD } // Server endpoints @@ -149,6 +151,10 @@ func (c *Config) Validate() error { c.Limits.MaxCustomEvents = 100 // Default } + if c.Limits.MaxMetricsPerMinute <= 0 { + c.Limits.MaxMetricsPerMinute = 30 // Default: 30 requests per minute + } + if c.Site.Path.MaxSegments < 0 { return fmt.Errorf("site.path.max_segments cannot be negative") }