Objective
Implement the exact case-insensitive stable directive-name union accepted by pinned ModSecurity 3.0.16 and Coraza 3.7.0, with typed schemas, deterministic source-anchored validation, capability discovery, and an immutable configuration model consumed by later execution issues.
WAF-12 owns directive recognition, argument/value validation, cross-directive constraints, build-capability rejection, and configuration introspection. WAF-13 through WAF-31 own later rule updates/actions/operators/body/audit execution. Recognition must never silently claim that an unavailable runtime capability exists.
Pinned executable inventory
The registry is tested against ModSecurity src/parser/seclang-scanner.ll and seclang-parser.yy at 7ea9fefbe0ba409d8733b4d682c8c4c059cd028d, Coraza internal/seclang/directivesmap.gen.go at 27069d06c896be74b77b9a6c0b539a0cbfaca360, and deployable OWASP CRS at 55b09f5acfd16413e7b31041100711ceb7adc89c.
Rules and identity
SecRule, SecAction, SecDefaultAction, SecMarker, SecComponentSignature, SecRuleEngine, SecConnEngine, SecConnReadStateLimit, SecConnWriteStateLimit, SecWebAppId, SecServerSignature, SecSensorId, SecStatusEngine, SecRuleScript.
Request, response, and protocol limits
SecRequestBodyAccess, SecRequestBodyLimit, SecRequestBodyNoFilesLimit, SecRequestBodyInMemoryLimit, SecRequestBodyLimitAction, SecRequestBodyJsonDepthLimit, SecResponseBodyAccess, SecResponseBodyLimit, SecResponseBodyLimitAction, SecResponseBodyMimeType, SecResponseBodyMimeTypesClear, SecArgumentsLimit, SecArgumentSeparator, SecCookieFormat, SecCookieV0Separator, SecStreamInBodyInspection, SecStreamOutBodyInspection, SecContentInjection, SecDisableBackendCompression.
Audit, debug, and external logging
SecAuditEngine, SecAuditLog, SecAuditLog2, SecAuditLogType, SecAuditLogFormat, SecAuditLogStorageDir, SecAuditLogDirMode, SecAuditLogFileMode, SecAuditLogRelevantStatus, SecAuditLogParts, SecAuditLogPrefix, SecDebugLog, SecDebugLogLevel, SecGuardianLog.
Filesystem and uploads
SecDataDir, SecTmpDir, SecUploadDir, SecUploadFileMode, SecUploadFileLimit, SecUploadKeepFiles, SecTmpSaveUploadedFiles, SecChrootDir.
Rule selection and compilation controls
SecRuleRemoveById, SecRuleRemoveByMsg, SecRuleRemoveByTag, SecRuleUpdateTargetById, SecRuleUpdateTargetByMsg, SecRuleUpdateTargetByTag, SecRuleUpdateActionById, SecRuleInheritance, SecRulePerfTime, SecInterceptOnError, SecIgnoreRuleCompilationErrors, SecCacheTransformations, SecPcreMatchLimit, SecPcreMatchLimitRecursion, SecRxPreFilter.
Remote, collections, lookup, hash, Unicode, and XML
SecRemoteRules, SecRemoteRulesFailAction, SecCollectionTimeout, SecGeoLookupDb, SecGsbLookupDb, SecHttpBlKey, SecDataset, SecHashEngine, SecHashKey, SecHashParam, SecHashMethodRx, SecHashMethodPm, SecUnicodeMap, SecUnicodeMapFile, SecXmlExternalEntity, SecParseXmlIntoArgs.
Aliases and capitalization differences map to one canonical entry. No additional Sec* name is accepted without an explicit registry change and compatibility evidence.
Typed registry and configuration model
Each entry defines canonical name and aliases; upstream/CRS presence; arity and repeatability; scope and ordering; typed value schema; runtime/build capabilities; security/redaction; owning downstream issue; upstream references; and positive/negative fixtures.
Schemas cover booleans, enums, bounded unsigned integers, octal modes, byte separators, paths, URLs, regexes, ID/range lists, audit-parts expressions, MIME values/lists, key/value pairs, and directive-specific tuples.
Compilation produces immutable typed settings and preserves every source span. Defaults are explicit. Repeated lists append in source order; singular directives follow documented baseline replacement/error behavior. Unknown names, bad arity, trailing bytes, overflow, invalid enums, unsafe paths/URLs, and contradictions fail before publication.
Capability and compatibility policy
- The official full build recognizes the complete union.
- Reduced builds return a stable unavailable-capability diagnostic during loading; no warn-and-ignore behavior.
- Baseline-unsupported directives still have schemas and explicit support states.
- Deprecated no-op compatibility requires an explicit
accepted_no_effectstate, docs, and evidence. - PCRE limit directives map to bounded zig-regex controls; production never links PCRE2.
- Remote rules require authenticated HTTPS, size/time limits, deterministic caching, and fail policy; fetching belongs to WAF-13.
- Paths are owned normalized values; subsystem owners perform confined I/O.
- Remote/hash/blocklist keys are redacted from diagnostics and introspection.
Diagnostics and limits
Stable WAF-DIRECTIVE-* codes carry primary/related spans for unknown/unavailable directives; arity/value/enum/integer/mode/separator/path/URL/regex/list/tuple failures; duplicate singular directives; conflicts; ordering/scope violations; missing companions; and secret-safe rendering.
Limits cover registry entries, configured directives, list items, range expansion, MIME types, path/URL/key/value bytes, total typed-setting bytes, diagnostic rendering, and remote/dataset declarations. Validation is iterative with checked arithmetic.
Deliverables
src/directives.zig: inventory, schemas, lookup, capability model, typed settings, validator, diagnostics, and introspection.- Plan/Builder integration that validates before publication.
- Exact pinned ModSecurity/Coraza inventory-drift CI tool.
- Positive/negative fixtures for every schema family and registry entry.
- Cross-directive/reduced-build tests.
- Allocation-failure injection, deterministic mutation fuzzing, repeated lifetime checks.
- ReleaseFast validation benchmark for small and CRS configuration.
- Documentation and machine-readable evidence.
Acceptance criteria
- Every pinned union name appears exactly once; aliases resolve deterministically.
- Every row links schema, capability state, owner issue, upstream presence, and tests.
- All 58 pinned files pass recognition/schema validation with zero unexplained exclusions.
- Deployable CRS validates as one ordered configuration set, not only unrelated files.
- Unknown, malformed, conflicting, or unavailable directives fail with stable spans.
- Numeric/mode/separator/list parsing is strict and overflow-safe.
- Secrets never appear in diagnostics, fingerprints, benchmarks, or debug introspection.
- Reduced builds reject every unavailable used directive before publication.
- Failed validation/build/reload leaves the active generation unchanged.
- Fingerprints match for semantically identical ordered settings.
- Exact Pantry Zig format/test/check, inventory drift, corpus, fuzz, allocation, benchmark, and hosted CI gates pass.
Relationships
- Parent: WAF-00
- Blocked by: WAF-10 and WAF-11, both complete.
- Blocks: WAF-13, WAF-21, WAF-35, WAF-36, WAF-63.
Baselines
ModSecurity 3.0.16; Coraza 3.7.0; OWASP CRS 4.28.0; Zig 0.17.0-dev.1441+d5181a9c9 through Pantry.