ReviewOS

zig-utils/zig-waf

[WAF-53] Implement signed policy bundles and rollout orchestration

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

Objective

Implement Ed25519 bundle signatures, validation, versioning, targeting, canaries, staged rollout, health gates, rollback, drift detection, and immutable history.

Deliverables

  • Implement the complete scoped behavior described above.
  • Keep request-path work independent from UI, PostgreSQL, and blocking audit I/O.
  • Use Zig 0.17-dev and dependencies pinned through Pantry; do not add Git submodules.
  • Keep public APIs explicit about ownership, resource limits, errors, security policy, and compatibility.
  • Add focused unit, integration, differential, fuzz, benchmark, and documentation coverage as applicable.

Acceptance criteria

  • The scoped implementation and tests are merged on main in small conventional commits.
  • Zig formatting, focused tests, and the relevant CI suite pass.
  • Compatibility claims have executable evidence and no unexplained skips or silent fallbacks.
  • Untrusted inputs have deterministic bounds; hot paths have benchmark evidence.
  • Documentation and the machine-readable compatibility matrix are updated.

Relationships

Blocked by

Blocks

Baselines

  • ModSecurity 3.0.16
  • Coraza 3.7.0
  • OWASP CRS 4.28.0
  • libinjection 4.0.0
  • Zig 0.17-dev resolved and locked through Pantry
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

Complete. Bundles are signed with Ed25519, rollout is staged and gated, and drift is visible.

Ed25519 signatures — signing originally used HMAC-SHA256, which is the wrong primitive here: a bundle is verified by every node, so the secret would have to reach all of them, after which one compromised node could forge a policy the whole fleet accepts. Signing is now asymmetric — nodes hold only the public key and the signing key never leaves the control plane (3bf0978).

Validation fails closed — another key's signature, an absent or unsigned version, content altered after publication, and a signature that is not well-formed hex of the right length are all false, never an error a caller might overlook.

Versioning and immutable history — (name, version) is unique and a published version is never rewritten, so a rollback is a rollout of an earlier version rather than an edit.

Targeting, canaries, staged rollout — assignment to one node, to a labeled cohort (labels jsonb), or fleet-wide, with per-version counts so convergence is observable.

Health gates — advanceIfHealthy widens a rollout only when every node already on the version is heartbeating within the window and has confirmed the version it runs. An empty cohort fails the gate: rolling out on the strength of a canary that was never deployed is the mistake a gate exists to prevent, so absence of evidence is not treated as evidence. A failed gate changes nothing (9a8722f).

Drift detection — nodes report the version they are actually running, and the control plane names those whose running version is not their assigned one, with both versions. A node that has never reported counts as drifted: silence is not compliance, and a new rollout re-opens drift for every node until each confirms again (e59b551).

Earlier slices: 4c65cee (signed bundles), fa2d79b (rollout assignments), b5b2797 (labeled cohorts), 3681484 (label segmentation). Documented in docs/fleet-storage.md.

Sign in to comment on this issue.