Skip to content

Diff by class, with provenance

Question this answers: "What did this change actually expose or break?"

Diff two policies and Firevyzer returns the exact traffic classes whose verdict flips — every one — each tagged with the rule that decides it now and the rule that decided it before. No packet-by-packet guessing; every changed class, with a cause.

Running a diff

The first policy you load is the baseline. As you edit — add, remove, modify, or reorder rules — the Changes panel diffs the effective flow space of your edits against that baseline and reports every verdict that flips.

The diff is semantic, not textual: a reordered, redundant, or fully shadowed edit that doesn't change any flow's verdict reports no effective change, even though the rule list looks different.

Reading the report

Changes are grouped into two kinds:

Newly allowed
Now permitted that previously was not — a potential exposure.
Newly denied
Now blocked that previously was allowed — a potential outage.

Each entry is a traffic class. Below it, the provenance lines attribute the change:

  • now by — the rule in the edited policy now responsible for the flow.
  • was by — the rule that decided it before (or the default-deny).

An over-exposed SSH rule

An admin SSH rule written without its port qualifier over-exposes all TCP to the host. The diff reports a single newly-allowed class:

tcp · any → 10.0.0.2 : any except 22
    now by  rule 3 · allow
    was by  rule 4 · drop

Everything on 10.0.0.2 except port 22 just became reachable — and you can see exactly which rule did it.

The report shape

For integrators, the diff is returned in this structure (rendered strictly from the match and provenance fields):

{
  "changed": true,
  "total_changes": 1,
  "newly_allowed": [
    {
      "match": {
        "dstip": "10.0.0.2",
        "proto": { "op": "eq",  "values": ["6"] },
        "dstpt": { "op": "neq", "values": ["22"] }
      },
      "provenance": {
        "deciding": { "index": 3, "action": "allow", "acl": "new" },
        "prior":    { "index": 4, "action": "drop",  "acl": "old" }
      }
    }
  ],
  "newly_denied": []
}
  • total_changes equals newly_allowed.length + newly_denied.length.
  • provenance.prior with index: -1 means the flow was previously decided by the implicit default-deny.
  • provenance is optional per entry — without it, a card still renders, just without the attribution lines.

Selecting a rule

Selecting a rule in the editor highlights the change cards it's responsible for (those whose provenance.deciding.index matches), so you can see a single rule's blast radius at a glance.

Scope it down

Pair the diff with a traffic scope to ask a narrower question — "did this change affect anything destined for 10.0.4.0/24?" The Changes panel then reports only the flips inside that scope, and tells you when your edits don't flip any verdict within it.

Next: Trace by traffic class