Add optional rule observer callback to WAF config#1478
Add optional rule observer callback to WAF config#1478heaven wants to merge 3 commits intocorazawaf:mainfrom
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1478 +/- ##
==========================================
- Coverage 85.28% 85.26% -0.02%
==========================================
Files 174 175 +1
Lines 8448 8472 +24
==========================================
+ Hits 7205 7224 +19
- Misses 994 997 +3
- Partials 249 251 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR introduces an optional rule observer callback that allows users to observe and inspect rules as they are loaded into the WAF during initialization. The observer receives rule metadata for each successfully added rule, enabling use cases such as logging, metrics collection, and UI representation of the active rule set.
Changes:
- Added
WithRuleObservermethod to theWAFConfiginterface for configuring the observer callback - Implemented observer invocation in
RuleGroup.Add()after a rule is successfully added - Added comprehensive test coverage with multiple scenarios
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| config.go | Added WithRuleObserver method to WAFConfig interface and implementation in wafConfig struct |
| waf.go | Integrated observer setup during WAF initialization by calling SetObserver on the Rules |
| internal/corazawaf/rulegroup.go | Added observer field and SetObserver method; invokes observer after rule is appended |
| waf_test.go | Added comprehensive tests covering observer functionality with and without observer configured |
|
I like this idea. But maybe moving it to the |
|
@jcchavezs WDTY? |
|
I like the idea too but I was thinking we should move this to experimental. We could
What do you think @heaven ? |
|
@jcchavezs I don't mind moving it. My goal was to make the footprint as small as possible, though, so I tried the opposite – to avoid new types and other exports. Then I found the almost identical |
|
@heaven no negative impact, the thing is:
|
|
@jcchavezs understood, thanks for the explanation. I'm working on moving this to the experimental package, but I ran into an issue. This is what I wanted to implement package experimental
import (
"github.com/corazawaf/coraza/v3"
"github.com/corazawaf/coraza/v3/types"
)
// ruleObserverCapable is the private capability interface
type ruleObserverCapable interface {
WithRuleObserver(func(rule types.RuleMetadata)) coraza.WAFConfig
}
// WAFConfigWithRuleObserver applies a rule observer if supported.
func WAFConfigWithRuleObserver(
cfg coraza.WAFConfig,
observer func(rule types.RuleMetadata),
) coraza.WAFConfig {
if c, ok := cfg.(ruleObserverCapable); ok {
return c.WithRuleObserver(observer)
}
return cfg
}But this creates a circular dependency, because package experimental
import (
"github.com/corazawaf/coraza/v3/types"
)
// ruleObserverCapable is the private capability interface
type ruleObserverCapable interface {
WithRuleObserver(func(rule types.RuleMetadata)) any
}
// WAFConfigWithRuleObserver applies a rule observer if supported.
func WAFConfigWithRuleObserver(
cfg any,
observer func(rule types.RuleMetadata),
) any {
if c, ok := cfg.(ruleObserverCapable); ok {
return c.WithRuleObserver(observer)
}
return cfg
} |
|
Because the core Alternatively, and since Of course, the best long-term solution would be to remove the dependency from the core |
Introduce an optional rule observer callback that is invoked for each rule successfully added to the WAF during initialization. The observer receives rule metadata via the existing RuleMetadata interface.
|
thanks for trying it. I will take it a stab |
Introduce an optional rule observer callback that invokes once for each rule successfully added to the WAF during initialization.
The observer receives rule metadata via the existing
RuleMetadatainterface, similar to the error callback. When unset, there is no behavioral or performance footprint.Reasoning
This change allows observing and inspecting the exact rule set Coraza uses internally, for example, giving the ability to represent those in the UI, eliminating the need to maintain a separate dataset, and keeping the source of truth unified.
The observer is intended for logging, metrics and inspection.