Skip to content

Response and proposals

Nyxtrace records and reviews response actions. In the free core it does not execute them: it changes no firewall, no endpoint and no remote system. Execution is the Pro feature response, and it runs only when a response target is declared in connectors.yaml — without one this page records proposals and decisions and executes nothing, exactly as before.

Saying that plainly is deliberate. A security tool that implies it contained something it merely logged is worse than one that contained nothing.

Since 0.32 the page opens with one line directly under its heading:

Calibration: Gate closed · learning phase until 24 Sep 2026 · precision 75 % · 4 labels in 14 d window

It is the tenant’s calibration gate — the appliance’s own bar before it executes anything without a person. The status word is one of three: Not started while no response target has run and no feedback was given (a supported state, not a fault), Gate open or Gate closed. The reason — the learning phase, too few labels, precision below the bar — is in the summary that follows, never a fourth status word. The line reads GET /api/v1/response/calibration; if that fails it says so with a Retry and the rest of the page is unaffected. What the numbers mean and how to move them is on the feedback page.

A response action is a proposal with a target and a written way back.

Field Meaning
Kind quarantine_device, block_destination, notify_only
Target The device or destination
Reason Why, in words
Rollback plan How to undo it, in words, written before approval
Requested by / approved by Who
Status One of twelve; a person writes approved, rejected, cancelled and rollback_requested, the executor writes the rest

A person can create a proposal and move it through Approve, Reject or Withdraw; every other transition is the executor’s. The rollback plan is a required field, not a convention. If you cannot write down how to undo an action, you are not ready to approve it.

Decisions need the Response or Administration role; each one carries a comment, the revision it was based on and an idempotency key.

What the card shows once a target executes

Section titled “What the card shows once a target executes”

With a response target configured and licensed, an approved quarantine_device or notify_only action is picked up by the worker, and the card grows two lines and a block:

Line Meaning
Held until The membership deadline, followed by the note the firewall expires the entry on its own even if this appliance is down — the fail-open backstop, stated where the lease is
Executor The executor’s last explanation, for example held on 2 node(s) until …; b: 3/3 states killed; a: 3/3 states killed, or the reason an attempt failed
Why Three lines of plain text — identity, evidence, policy — explaining what the gate saw. Described below

A card that belongs to a canary (since 0.37) is labelled Canary · synthetic chain check, not a detection and walks the same lines; the incident behind it is titled Canary: synthetic response chain check and closes itself at the canary’s ttl.

Every apply, human or automatic, resolves and stores the same three things, and the card shows them together under one heading — plain text, no badges, because none of it is a lifecycle status:

Why
Identity: DHCP lease and MAC · 3 anchors, fresh 12 min ago · fresh lease: stable MAC 02:de:96:14:00:02 from dhcp-leases seen 2026-09-12T11:50:00Z
Evidence: Zeek, DNS, Threat intel · Resolver blocked, First sighting, Scan
Policy: proposal · revision 3 · score 96 at or above automatic threshold 95; calibration gate closed: learning phase until 2026-09-24
Line What it reads
Identity The proof grade — None, DHCP lease and MAC, Static binding or Enrolled — then how many anchors it was judged on and how fresh the deciding one is, then the reasons in words. A grade the page does not know is shown verbatim
Evidence The independent classes behind the incident — Zeek, Suricata, NetFlow, DNS, Threat intel, Behaviour model, Mail — then the markers (Threat intel match, Resolver blocked, Beaconing, Scan, First sighting, Rare recurrence, Baseline deviation, Analyst false positive), then analyst verdict: … once the incident has feedback
Policy The mode (proposal for every human approval and for a proposal the producer held; automatic for an action the appliance approved itself), the policy_revision it was taken under, and the gate’s reasons in order — the candidate line, the identity reasons, the confidence basis (class zeek 0.50 … evidence confidence 0.90 (revision 1)), and last the reason that decided

The last policy reason is the one to read first. On a proposal the producer held it names the gate that said no — calibration gate closed: learning phase until 2026-09-24, identity proof none below dhcp_lease_and_mac, or the cap. On an action the executor reopened after a refusal it reads reopened for a person: ….

An action the appliance produced itself shows nyxtrace:automatic as the requester. When the calibration gate was open it is also the approver, the policy line says automatic, and the card walks the executor’s statuses like any approval — there is no separate lane and no separate vocabulary. When the gate was closed the card is an ordinary Proposed card with Approve, Reject and Withdraw, and the policy line tells you it would have been automatic. Deciding those proposals is the learning phase; the verdicts that open the gate are given through response feedback, not through the buttons.

The status line reads the executor’s progress: Executing → Executed (held on every node), or Reconciling (partial application) while a node is outstanding, or Failed with the reason — a target outside the allowed ranges, inside a protected scope, an address that meanwhile moved to another device, the kill switch, a node that refused, or, on an automatic action, a gate that no longer held when the executor re-checked it. An approval without a target, or without the licence feature, stays Approved (waiting for the executor) with the reason in the policy line, documented and inert.

block_destination is never executed; it stays a proposal by design.

An action that is Executed, Reconciling or Executing offers Release. It records the intent as Release requested; the worker then removes the entry — standby node first — and the action becomes Released (absence confirmed) only once every node confirmed the entry is gone. A node that could not confirm leaves it at Releasing with the reason in the executor line, and the worker retries. Release is never licence-gated: what was applied under a licence stays reversible after it lapsed.

At the deadline the appliance releases on its own and the action ends as Expired (deadline passed); on the firewall target the alias expiry has usually removed the entry already.

A false_positive verdict through response feedback presses Release on every held action of the incident at once and cancels an automatic one that was approved but not yet applied. It needs the same role.

The card shows the executor’s summary; the individual companion calls — one row per node and operation, with the correlation id, the timing, the readback (null when the readback itself failed, false when the entry is absent), the states seen and killed and the failure class — are returned by GET /api/v1/response-actions/{id}. See the endpoints. Node labels are your own (a, b, unifi); alias names, node addresses and state ids never leave the server.

The same review mechanism carries every change that a model or an analyst wants and a person must approve:

Kind Proposes
device_classification A device type and owner, from existing metadata
model_author A new detection model, as validated YAML
triage A threshold or exception change, from false-positive feedback

Every one is stored as a tenant-scoped proposal with a status, a revision, the requester and timestamps. A decision is a separate call carrying the revision it was based on and an idempotency key.

Three rules make this more than a formality:

Approving a model proposal does not activate the model. It records that a person considers it good. Activation is a separate deployment step.

Approving a triage proposal does not change a threshold. Same reason.

Approving a classification proposal applies exactly two fields — the suggested device type, and the owner if one was suggested — with the normal classification audit trail. It does not touch the display name or the tags, and a suggested null owner preserves the existing owner rather than clearing it.

A model proposal is only stored at all once its generated YAML validates against the safe model language. Invalid output does not become a pending item for a human to puzzle over.

Marking an incident as a false positive, or rating a model result as useful or not, records tenant-scoped human feedback. It never retrains or activates anything automatically. It is input for a triage proposal that a person then reads.

Executing a human approval shipped in 0.31; the automatic mode has a producer since 0.32 and is off by default twice over — auto_enabled on the response target and the calibration gate both default to no. Until both say yes, everything the producer would execute arrives on this page as a proposal for a person, with the reason under Why. The plan’s gates still stand — an isolated test of the target firewall pair, a live canary against an address the operator owns — and the overview lists the six steps in order. See also the roadmap.

The rules already written down hold: a model never blocks on its own, containment goes through the deterministic layer with a score threshold and either an approval or an open calibration gate, and a lapsed entitlement never leaves an existing block hanging — release is not licence-gated, and on the firewall the expiry mechanism is independent of the appliance altogether.