Skip to content

Wardex v1.9.2

Choose a tag to compare

@had-nu had-nu released this 10 May 00:42
· 325 commits to main since this release

Wardex v1.9.2 — Completing Incomplete Behaviours in wardex evaluate

Patch release that closes three gaps between what the wardex evaluate command
announces as its contract and what it delivers. No new features. No breaking changes.

Background

The architecture of Wardex describes a pipeline in three steps: canonicalised evidence
in, signed configuration applied, auditable decision out. Two of the three steps were
implemented. The decision was taken; the signed configuration was verified. The decision
was then written to stdout and discarded. v1.9.2 completes the third step.

Fixed

G1 — Gate decision log. wardex evaluate now appends a JSONL entry to
wardex-gate-audit.log (configurable via --gate-log) at the end of each evaluation.
The entry records: timestamp, config hash, evidence hash (SHA-256 of the --evidence
file), overall decision (allow / warn / block), risk score, and a human-readable detail
field. The log uses the same AuditLog() mechanism already in use for acceptances —
mutex-protected, append-only, safe path.

G2 — Evidence provenance validation. wardex convert now populates a
converted_by field in the canonical evidence envelope (e.g.
converted_by: "wardex-convert/grype"). wardex evaluate checks for the presence of
this field and emits a warning when it is absent — indicating that the evidence file
may not have been canonicalised and that missing fields (reachable, epss_score)
will default to conservative values silently. With --strict, an evidence file without
converted_by exits with code 3.

G3 — Decision log forwarding. The Forwarder interface and SyslogBackend in
pkg/accept/forward.go are now connected to the gate decision log path. Configuring
reporting.gate_log.forward: ["syslog"] in wardex-config.yaml causes each gate
decision entry to be dispatched to the configured backend immediately after local write.
on_fail: "warn" (default) does not block the pipeline if forwarding fails;
on_fail: "block" exits with code 3.

Added

  • model.AuditEntry: two new omitempty fields — evidence_hash and
    overall_decision. Existing acceptance audit log entries are not affected.
  • model.VulnerabilityEnvelope: new wrapper type with converted_by and
    vulnerabilities. wardex evaluate now deserialises to this type; wardex convert
    populates converted_by.
  • config.GateLogConfig / reporting.gate_log block: path, forward, on_fail.
    Optional; defaults to wardex-gate-audit.log, no forwarding, on_fail: warn.
  • cmd/evaluate/evaluate_gate_log_test.go: tests for log creation, append behaviour,
    and correct field population.
  • cmd/evaluate/evaluate_provenance_test.go: tests for warning on missing
    converted_by, strict rejection, and clean pass on canonical input.

Compatibility

Evidence envelopes without converted_by (all existing pipelines) continue to load
and evaluate without error. The new behaviour is a warning, not a block, unless
--strict is set. The wardex-gate-audit.log is a new file created in the working
directory; pipelines that do not want it can set --gate-log /dev/null.

Upgrading

go install github.com/had-nu/wardex@v1.9.2

Existing pipelines require no changes. To opt into strict provenance validation:

wardex evaluate --strict --config wardex.wexstate --evidence wardex-vulns.yaml

To enable syslog forwarding of gate decisions, add to wardex-config.yaml:

reporting:
  gate_log:
    path: wardex-gate-audit.log
    forward: ["syslog"]
    on_fail: warn

What's next

Deferred items from this release: cryptographic chaining of decision log entries
(each entry hashing the previous), additional forwarding backends beyond syslog
(S3, GCS, Rekor), and per-vulnerability granularity in the decision log. These are
improvements to the log's tamper-evidence properties, not to its core function;
the core function — a persistent, auditable record of each gate decision — ships
in v1.9.2.