ReviewOS

zig-utils/zig-waf

[WAF-15] Implement disruptive, flow, chain, skip, and ctl actions

#16
Closed chris opened this 9 days ago ·
9 days ago

Objective

Compile and execute the stable ModSecurity 3.0.16 / Coraza 3.7.0 union of disruptive, flow-control, chain, multi-match, and runtime control actions using typed immutable plan data and bounded transaction-local state. Decisions must compose atomically with WAF-14 metadata/non-disruptive effects and never require audit, UI, network, or database I/O on the request path.

Deliverables

Typed plan ABI and validation

  • Compile allow, block, deny, drop, pass, proxy, redirect, and status into typed descriptors; validate values and incompatible or duplicate action families before publication.
  • Preserve block as delegation to the phase SecDefaultAction disruptive action, including its effective status.
  • Compile allow scopes (phase, request, and transaction/default scope), macro-bearing redirect/proxy destinations, and status codes with stable diagnostics.
  • Compile bounded skip, statically/dynamically resolved skipAfter, chain, and multiMatch execution metadata without request-time plan mutation.
  • Compile the stable runtime ctl union: ruleEngine, auditEngine, auditLogParts, requestBodyAccess, responseBodyAccess, requestBodyProcessor, requestBodyLimit, forceRequestBodyVariable, ruleRemoveById, ruleRemoveByTag, ruleRemoveTargetById, and ruleRemoveTargetByTag.
  • Reject unavailable proxy execution explicitly; never silently treat it as pass.

Atomic match and chain decisions

  • Extend WAF-14 matched-rule/chain application so metadata, captures, local/persistent effects, runtime controls, flow decisions, match intent, and intervention intent either commit together or leave transaction state unchanged.
  • Only a fully matched chain executes actions; use chain-head metadata/disruptive semantics while retaining member actions in source order where upstream semantics require them.
  • Detection-only mode records the same disruptive evidence but does not interrupt phases, terminate inspection, redirect, proxy, or pause connector I/O.
  • Enforce deterministic conflict/precedence semantics for defaults, rule actions, status, and repeated controls.

Flow execution API

  • Add a bounded per-phase execution cursor over immutable phaseRules that applies skip, skipAfter, allow scopes, disabled rules/tags, and terminal decisions without allocation in steady-state iteration.
  • skip counts executable chain heads, not chain members or markers; skipAfter resumes at the compiled same-phase rule after the selected marker.
  • allow:phase, allow:request, and bare allow stop exactly the upstream-defined future phase scopes while phase-5 logging remains reachable exactly once.
  • pass does not interrupt execution; deny, redirect, and drop expose connector-owned interventions; drop terminates later inspection but not logging.
  • Define connector contracts for redirect location ownership, proxy destination ownership/capability, and drop behavior; reserve pause capability/intervention ABI while WAF-21 owns bounded duration parsing and execution.

Runtime controls and exclusions

  • Store engine/audit/body controls transaction-locally with phase legality checks.
  • Implement bounded rule-id intervals, exact rule-tag exclusions, and exact/regex rule-target exclusions by id/tag with deterministic matching and zig-regex limits.
  • Apply controls only to subsequent rule/target evaluation, never retroactively to the committing rule.
  • Expose read-only control state for body processors, audit writers, connectors, event records, and the future C ABI.

Evidence and qualification

  • Add focused unit/integration tests for every action/value/precedence/error path, chains, all five phases, detection-only, lifecycle boundaries, and allocation rollback.
  • Add pinned ModSecurity/Coraza differential fixtures and relevant CRS 4.28 control/exclusion cases with an executable evidence manifest.
  • Add deterministic fuzzing for action/control parsing and execution-state transitions with hostile values and bounded collections.
  • Add ReleaseFast benchmarks for decision commit, execution cursor, rule exclusions, and dynamic skipAfter; record allocations, throughput, and p50/p95/p99.
  • Update the compatibility matrix, architecture/action documentation, and feature discovery only after executable evidence passes.

Acceptance criteria

  • Every listed stable action has a typed compiled representation, stable malformed-input diagnostic, runtime test, and upstream/CRS evidence reference.
  • No partial state is observable after allocation failure, invalid macro expansion, unavailable proxy capability, illegal late control, persistence failure under fail-closed policy, or intervention conflict.
  • Untrusted counts, strings, macro expansion, intervals, exclusions, regex work, pause duration, redirect/proxy destination, and control storage have deterministic limits.
  • Request-path decision/cursor benchmarks perform no blocking I/O and demonstrate bounded allocation behavior.
  • Zig checks, focused fuzz/evidence steps, ReleaseFast benchmarks, formatting, and hosted CI pass on the exact closing SHA.
  • Work lands directly on main in small conventional commits with issue/commit links; no submodules or silent compatibility fallbacks are introduced.

Tests

  • Parser/plan: values, defaults, overrides, macros, static/dynamic markers, control grammar, and limits.
  • Engine: atomic rollback, chain order, allow scopes, detection-only, intervention precedence, body-control timing, exclusions, exactly-once logging.
  • Differential/evidence: pinned ModSecurity and Coraza action/control suites plus CRS 4.28 control/exclusion rules.
  • Security: malformed intervals, hostile regex selectors, macro limits, redirect policy input, allocation-failure exhaustiveness.
  • Performance: pass/deny/redirect/control commits, no-op and exclusion-heavy cursors, dynamic marker resolution.

Relationships

Blocked by

Blocks / feeds

Baselines

  • ModSecurity 3.0.16 at 7ea9fef
  • Coraza 3.7.0 at 27069d0
  • OWASP CRS 4.28.0 at 55b09f5
  • Zig 0.17-dev resolved and locked through Pantry
9 days ago

WAF-09 (#10) now explicitly blocks this scope. Its implementation contract covers bounded TX mutation plus persistent IP/SESSION/USER/GLOBAL/RESOURCE initialization, expiration, atomic conflict-safe updates, failure policy, and real Pantry-managed LMDB persistence.

Do not duplicate or weaken those semantics here; consume the WAF-09 engine/backend APIs once qualified.

9 days ago

WAF-09 (#10) is complete on main and hosted-qualified: https://github.com/zig-utils/zig-waf/actions/runs/29939075574

This issue may now consume the stable TX/persistent collection, action-facing identity binding, expiry, atomic mutation, failure-policy, capability-discovery, in-memory, and LMDB contracts. Preserve typed errors and do not add an alternate persistence path.

9 days ago

Dependency update: WAF-11 #12 is complete at 19b64bc with exact hosted CI green. This issue can now consume the immutable typed IR, stable diagnostics, prefilters/macro programs, fingerprints, shared payloads, and explicit WAF plan ownership contract.

9 days ago

WAF-13 published the immutable marker/skipAfter plan prerequisite at 7c4a58c. WAF-15 can consume pre-resolved static resume rule IDs and allocation-free dynamic resolveMarkerAfter lookup; final builders reject unresolved static targets as WAF-PLAN-0114.

9 days ago

Implementation started on main with 6d1c842 (feat(engine): parse disruptive action configuration). This adds allocation-free typed parsers and focused tests for allow scope, bounded HTTP status, positive skip counts, rule-engine mode, audit-engine mode, and strict on/off runtime controls. Next: compile these values into immutable typed plan descriptors with stable diagnostics and independent resource limits.

9 days ago

Typed plan tranche pushed on main as 3b936ef (feat(engine): compile disruptive rule decisions). Plan ABI 6 now stores effective decisions for allow/block/deny/drop/pass/proxy/redirect/status plus bounded skip, skipAfter, and multiMatch metadata. block resolves against its phase default at compile time; destinations retain compiled macro programs; malformed/conflicting values report WAF-PLAN-0119. All 202 tests and zig build check pass locally.

9 days ago

Flow runtime landed in two small main commits: 4fe2b71 adds the exported allocation-free per-phase cursor with executable-chain-head skip and allow-scope behavior; b09eaaa adds typed skipAfter target indexes plus atomic static/dynamic macro resolution against staged same-rule effects. The cursor resumes after the marker, keeps phase-5 logging reachable, and returns stable lifecycle/reference errors. All 205 tests and zig build check pass locally.

9 days ago

WAF-14 #15 is complete and unblocks this issue at exact green SHA 28380d45c92a01a9ed48a7b63784ae26a59a5bab (CI: https://github.com/zig-utils/zig-waf/actions/runs/29959702219).

9 days ago

Runtime control foundation is now on main: 3e86c4a adds strict allocation-free control grammar, 16f6a85 adds the separately bounded immutable plan table and WAF-PLAN-0120, and ec3bff3 atomically applies rule-engine, audit-engine, request-body access/limit/processor, force-body, and response-body access state. Same-rule macros affect enforcement deterministically; Off stops the cursor; malformed/late controls roll back all match state. The suite is 211 tests green locally and the pinned five-root corpus remains 58/58 plans.

9 days ago

Exclusion/audit tranche pushed on main: 70750ca enforces bounded subsequent-rule ID/tag exclusions; 4ba3fc5 atomically stages exact target exclusions by ID/tag and exposes target filtering, with regex-delimited selectors explicitly unavailable pending bounded zig-regex compilation; 753d0cd implements canonical absolute and +/- auditLogParts state. Allocation-failure qualification now covers owned rule/target exclusions. All 215 tests and zig build check pass locally.

9 days ago

Connector/allow qualification pushed: 329ecac makes proxy an explicit builder capability and rolls back the entire match when unavailable; de74ef6 proves allow:request resumes at response headers, bare allow suppresses remaining inspection, and logging always remains reachable. No connector downgrade-to-pass behavior exists.

9 days ago

Cross-repository blocker resolved: zig-regex#18 is implemented on zig-regex/main as 957013d. The fix makes regex parser tree construction exhaustive-allocation-failure safe and is now used by the regex-delimited ctl:ruleRemoveTargetById/Tag implementation in this issue. Hosted qualification of the exact regex SHA is in progress.

9 days ago

Regex-delimited runtime target exclusions are implemented and pushed to main in ba9c150.

Delivered:

  • allocation-free parsing of exact versus COLLECTION:/pattern/ targets;
  • static ruleset validation with zig-regex;
  • transaction-owned, pointer-stable compiled selectors and per-transaction workers;
  • ID/tag scoping, collection-name matching, bounded count/bytes, and propagated matcher-limit errors;
  • atomic staging/rollback across all allocation failures;
  • exact + regex positive/negative tests.

Cross-repository dependency: zig-regex@1b2293e, tracked by zig-regex#18.

Local Pantry Zig 0.17 qualification: zig build test --summary failures — 218/218 pass. Awaiting hosted CI for the exact WAF and regex SHAs.

9 days ago

zig-regex#18 is now closed. Exact pinned SHA 1b2293e passed hosted CI run 29963261202 across tests and all build targets.

9 days ago

Implementation qualification is green on exact SHA 0b80370: hosted run 29963857555. Every workflow step passed, including lock/no-submodule verification, 219 tests, compile, CRS configuration, five-root parser/plan/directive corpora, all four 10,000-case fuzzers, and every ReleaseFast benchmark.

The compatibility row is now verified, the evidence manifest records the implementation gate, the issue checkboxes are complete, and pause scope is explicitly linked to WAF-21 rather than silently published. Final closing commit: 194ac92. Awaiting its exact hosted run 29964287029 before closing this issue.

9 days ago

Completed and verified on main. Final closing commit: 194ac92. Exact closing-SHA CI: run 29964287029 — every lock, no-submodule, format, test, compile, pinned corpus, fuzz, and ReleaseFast benchmark step passed.

Key linked delivery commits include 6d1c842 through 344dc8c, regex target exclusions in ba9c150, dependency pin 6f2ae28, cursor benchmarks b8c21fb, and portable rollback qualification 0b80370. The linked allocation-safety blocker zig-regex#18 is also closed and green.

The verified compatibility row and executable evidence feed WAF-16 #17, WAF-21, body/audit work, connector ABI, SRTS, and CRS qualification.

Sign in to comment on this issue.