Decision plugins are compiled Go shared libraries (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/tilsor/ModSecIntl_wace_lib/llms.txt
Use this file to discover all available pages before exploring further.
.so files) responsible for producing the final block/allow verdict for each transaction. When CheckTransaction is called, WACElib waits for all synchronous model plugins to finish, collects their results, and passes everything to the named decision plugin’s CheckResults function. The decision plugin receives both the ML model outputs and any WAF scoring parameters forwarded from the OWASP Core Rule Set, allowing it to combine signals from both sources before deciding.
Field reference
Unique identifier for this decision plugin instance. Passed as the second argument to
CheckTransaction to select which plugin evaluates the transaction.Filesystem path to the compiled
.so decision plugin file. Must exist and be readable when Init is called. An empty or non-existent path causes Init to return an error.Numeric weight given to WAF signals relative to model outputs. The interpretation is left to the plugin implementation; WACElib stores the value and makes it accessible during plugin initialisation via
params, but does not enforce any semantics on it directly.In the YAML representation the key is
wafweight (all lowercase). In the Go struct configFileDecisionPlugin the corresponding fields wafweight and decisionbalance are unexported, so they are populated only via YAML unmarshalling — they cannot be set programmatically from outside the package.Balance factor between WAF signals and model predictions. As with
wafweight, the exact meaning is defined by the plugin; WACElib passes the value through unchanged.Arbitrary key/value string map passed verbatim to the plugin’s
InitPlugin function at load time. Use this to supply plugin-specific configuration without modifying plugin source code.The DecisionInput struct
WhenCheckTransaction calls a decision plugin, it constructs a DecisionInput value from pluginmanager and passes it to CheckResults. Understanding the struct is essential for writing correct decision logic.
| Field | Type | Description |
|---|---|---|
TransactionId | string | The transaction ID passed to InitTransaction. |
Results | map[string]ModelResults | Map of model plugin ID to its result. Only contains results from model plugins that completed before CheckTransaction was called (i.e. sync plugins only). |
ModelWeight | map[string]float64 | Map of model plugin ID to the weight value from its configuration. Keys match Results. |
WAFdata | map[string]string | The wafParams map passed directly to CheckTransaction by the caller — typically OWASP CRS anomaly scores. |
ModelResults is also defined in pluginmanager:
ProbAttack is a value between 0 and 1 representing the model’s estimated probability that the transaction is an attack. Data carries any additional structured output the model plugin chooses to return.
WAF parameters
TheWAFdata field in DecisionInput contains the key/value map supplied by the WAF integration layer — for example, OWASP CRS anomaly scoring variables forwarded from ModSecurity or Coraza. A representative set of keys looks like:
simple reference plugin, for example, reads inbound_blocking and inbound_threshold to determine whether Coraza is recommending a block:
Configuration examples
Minimal decision plugin
With WAF and balance weights
Full configuration with model plugins
The following is a complete working configuration combining two model plugins and one decision plugin, taken from the WACElib test suite:Plugin interface contract
Decision plugins must export two functions. WACElib looks them up by name at load time via Go’splugin package.
Calling CheckTransaction
Pass WAF scoring parameters as the third argument. An empty map is valid and causesWAFdata to be empty inside the plugin.