Response actions on an endpoint
Every action the platform can take on a machine, which are reversible, which may run unattended, who is allowed to raise one, and the approval flow.
A detection tells you something happened. A response action does something about it. This article is the complete list: every action the platform can take on one of your machines, what each one costs to reverse, which of them may ever run without a person, and how a proposed action becomes an executed one.
It also answers the question people ask first and find hardest to get a straight answer to: can I press a button and make something happen on a machine? For six of the seven commands, no. Read the next section before anything else.
Who is allowed to raise an action
This is the part that surprises people, so it goes first rather than in a footnote. In the shipped console there is no screen that lets a person create a response action. Not on Endpoints, not on an incident, not on an alert, not on a ticket.
What a person can do is answer actions that the platform has already proposed, and start the two reversals.
| Command | Created by | Your controls |
|---|---|---|
isolate | Sentinel-Q's automatic response, its second-tier response, or the playbook engine | Approve or Reject on the Tickets screen |
kill_process | The same three | Approve or Reject on the Tickets screen |
quarantine_file | Sentinel-Q's containment chain, including the one automatic path below | Approve or Reject, and Undo once it has completed |
fetch_file | The same three | Approve or Reject on the Tickets screen |
shell | Nothing raises one in the shipped console | None. Every sensor refuses it anyway |
unisolate | You — Endpoints → Restore network access | Press it. Created and approved in one step |
restore_file | You — Tickets → Undo on a completed action | Press it |
One consequence worth internalising: if Sentinel-Q is not licensed or not enabled for your organisation, nothing will ever raise an endpoint action, and your Tickets screen will stay empty for ever. That is not a fault. It is what the product does when the only thing that proposes actions is switched off.
Two systems, one of which is real
There are two response mechanisms in the product and they are easy to conflate. The distinction matters because one of them executes on a machine and the other partly does not.
- Live response
- Signed tickets executed by the sensor on a specific host. This is the real one, it is what every documented action below runs through, and it is covered in detail in Live response and approval.
- Response actions and playbooks
- An older model that defines an action once and executes it against a target. Three of its action types — killing a process, isolating an endpoint and quarantining a file — now create real live-response tickets underneath. One does not.
Every action, by its exact name
These are the literal command strings. They appear on tickets, in audit records and in error messages, so they are worth recognising.
| Command | What it does | Reversible | Status |
|---|---|---|---|
fetch_file | Copies a file from the machine to the platform, and reports its SHA-256 digest. | Nothing to reverse — no state on the machine changes. | Works on Windows, Linux and macOS. |
kill_process | Terminates one process by its process ID. | No. A terminated process cannot be restored. | Works on all three. |
isolate | Cuts the machine off the network except for the Qorionix control plane. | Yes. Endpoints → Restore network access, or unisolate. | Works on all three. |
quarantine_file | Moves a file into a protected vault on the machine and strips all access to it. | Yes. Tickets → Undo on the completed ticket, or restore_file. | Works on all three. |
shell | Would open an interactive shell session. | Not applicable. | Stubbed. Always refused. |
unisolate | Restores the machine's network access from the snapshot taken before isolation. | It is the undo. | Works on all three. |
restore_file | Puts a quarantined file back at its original path, refusing to overwrite anything already there. | It is the undo. | Works on all three. |
run_script | Runs one allowlisted, sensor-locally-provisioned script by name. | No undo command is wired for it yet — see the dedicated article. | Works on all three. See Response scripts and run script. |
A shell ticket can be created and every platform refuses it with the same sentence:
shell sessions disabled in this sensor build
That is deliberate rather than unfinished. An interactive shell on an endpoint is the most powerful capability a security product can hold, and it is gated behind a future privileged-session proxy so that every keystroke is recorded. Shipping it before the recording exists would mean the most sensitive thing in the product is also the least auditable.
How an action actually runs
Every action is a ticket, and every ticket walks the same path regardless of who or what raised it. Six statuses exist; the four below are the happy path, and the other two — rejected and expired — are where a ticket stops early.
Created — and it starts as pending
A ticket names one organisation, one sensor, one command and who requested it. Its status is set to
pending_approvalunconditionally. There is no path that creates an already-approved ticket, including for the platform's own automation. Tickets raised by the detection engine record their requester assentinel-q-autoresponse, so a machine-raised action is distinguishable from a human-raised one in every list you will ever read.Given a blast radius
Each ticket carries a blast radius, defaulting to
high. Two commands default tolowinstead:unisolateandrestore_file. That is deliberate — if an undo landed in the same queue with the same urgency as the action it reverses, a reversible action would stop being reversible in practice.Approved by a person
One approval is required by default. The threshold is adjustable. Reaching it signs the ticket cryptographically and moves it to
approved. Approving needs the response-actions write permission.Collected by the machine
The sensor asks the platform for work on a long-lived connection and receives at most sixteen tickets at a time, only those that are approved and not yet expired. Each ticket handed over is immediately marked
dispatched, so a ticket cannot be collected twice.Completed, with a result
The sensor reports back with a status and a detail string. Status becomes
completed. The detail is stored on the ticket and is what you read in the console as the outcome — including when the outcome is a refusal.
The full set of ticket statuses is pending_approval, approved, dispatched, completed, rejected and expired. The console shows them as Awaiting approval, Approved, Dispatched, Completed, Rejected and Expired.
Which actions may run without you
Exactly one, and only by one route: quarantine_file, when it was raised by a threat-intelligence file-hash match. Nothing else in the endpoint module is eligible for automatic approval, at any tier, at any confidence.
Four conditions must hold together for that one case:
- The autonomous capability is enabled on your cell at all — a deployment-level switch, off unless it was turned on.
- The rule that raised the ticket is set to tier 2. Only the built-in known-bad-hash rule can be.
- The indicator's confidence is at or above the floor, which defaults to 0.95.
- No policy of yours downgrades that rule. A policy row that is present but disabled reads as recommend, not as auto.
Fail any one and the ticket waits for a person like everything else. Every behavioural rule is capped at recommend by the server, so no amount of configuration turns a behavioural detection into an automatic action — attempting it is refused with 422 and a message naming the ceiling. Autonomy tiers: observe, recommend, act covers the tiers themselves.
Undo, and the defect that used to be here
Earlier versions of this article carried a warning that an undo could not reach a machine at all. That defect is fixed, and the correction is recorded here rather than quietly deleted, because you may have read the warning and planned around it.
What was wrong: the sensor kept its own list of commands it would act on, and that list was never widened when the two undo commands were added. It knew about fetch_file, kill_process, isolate, quarantine_file and shell, and not about unisolate or restore_file. An undo therefore arrived at the machine and came back refused, while the action that caused it had worked — which is the worst possible shape for a reversibility guarantee to fail in, because the operator has already been told the action is reversible.
An undo that fails silently on the way out is worse than no undo, because the operator has been told the action is reversible.
What changed: the second list was removed rather than extended. The per-platform dispatchers already refuse anything they do not implement, and the signature check is what actually bounds what may be run, so the narrowing now lives in exactly one place instead of two that could drift apart. Both undo commands are reachable end to end.
What is built now. The server accepts both undo commands, creates a ticket and signs it. The un-isolate call creates and self-approves in one step — the operator pressing the button is the human in the loop, so what is skipped is the waiting, not the recording: the ticket row, the approval row naming the operator and the signature are all written exactly as normal. Both undo calls derive their arguments from the sensor's own recorded evidence rather than from whoever is calling, which is what makes them safe: a file path supplied by an HTTP caller and executed as root on an endpoint is a write-anywhere primitive. All three operating-system dispatchers implement both commands.
If the machine cannot be reached. The undo still has to travel to the host, and a host that is switched off or has stopped checking in will leave the ticket sitting at Dispatched. Two manual routes exist, and both need somebody who can reach the machine.
- Run the ticket locally. The sensor has a subcommand that executes a signed ticket from a file —
zentryq-sensor live-response --ticket <file>— which reaches the same per-platform code the console does. Ask us for the ticket file for the action you want reversed. - Reverse it by hand from the recorded evidence. Every isolation and every quarantine records what it did and how to reverse it, on the ticket, at the time. The isolation evidence carries a literal command to run. The quarantine evidence carries the file's original path and its SHA-256 digest, and the file itself is sitting in the vault under that digest.
The exact commands and paths for un-isolating are in Isolating a machine. For a quarantined file, the vault is C:\ProgramData\ZentryQ\quarantine on Windows and /var/lib/zentryq/quarantine on Linux and macOS, and the file is stored as <sha256>.bin with all access removed. Restoring means putting those bytes back at the recorded original path with sane permissions — which is exactly what restore_file does, and it refuses to overwrite an existing file at the destination while doing it.
What reversal actually restores
Each action records how it is undone at the moment it is taken, by the code taking it, rather than being reconstructed afterwards by somebody reading logs. Those recorded instructions are the ones below, verbatim.
| Action | Reversal | The recorded instruction |
|---|---|---|
| Isolate an endpoint | unisolate | "Open the live-response ticket and issue the counter-command to restore network access, or cancel the ticket if the sensor has not yet collected it." |
| Quarantine a file | restore_file | "The original bytes are preserved in the sensor's quarantine vault under their sha256 manifest; restore from there." |
| Kill a process | Cancel the ticket only | "Cancel the live-response ticket if the sensor has not yet collected it. A process that has already been terminated cannot be restored; restart the service through normal change management." |
| Fetch a file, open a ticket | Cancel the ticket | "Cancel the live-response ticket. No endpoint state was changed." |
The kill_process entry is the model for how this product talks about irreversibility. It does not imply a rollback that does not exist. It states plainly that a killed process cannot be un-killed, and then offers the only thing that genuinely is reversible — cancelling the ticket before the machine has collected it.
An action with no known reversal produces no undo handle at all, and a missing handle is treated as this must not be taken autonomously. That is the same rule the rest of the platform uses; Undoing a change Qorionix made covers it from the other side.
A quarantine that did not record both the original path and the digest cannot be undone automatically, and says so rather than guessing:
liveresponse: this action has no counter-command and cannot be undone automatically:
the quarantine result for ticket <id> did not record both original_path and sha256,
so there is nothing to restore fromRefusals you will see on a ticket
A sensor refusing an action is different from a sensor failing at one, and the two are reported differently on purpose — retrying a refusal will not help. The strings below are what appears as the ticket result.
shell sessions disabled in this sensor build
unknown command: <cmd>
missing or invalid pid
refusing to kill init (pid 1) (Linux)
refusing to terminate System (pid 4) (Windows)
refusing to kill launchd (pid 1) (macOS)
control_plane_cidr is required for isolate
missing path
file exceeds 10485760 bytes (Linux)
file too large (Windows, macOS)
sha256 and original_path are both required for restore_file
sha256 must be a 64-character lowercase hex digest
no quarantined file with digest <sha256>
refusing to overwrite existing file at <path>The three refusals to kill process 1 — or process 4 on Windows — are guards, not bugs. Terminating the operating system's own root process takes the machine down, and no detection is confident enough to be worth that.
On the server side, the ones worth recognising are liveresponse: ticket not approved with 409, liveresponse: ticket expired with 410, and liveresponse: not found with 404. Attempting to undo a ticket that is not finished answers with the state it is in:
ticket <id> is <status>, not completed: reject or let it expire instead of undoing itThe reusable action catalogue, on Response → Response actions
Everything above describes a ticket, which is the thing that actually reaches a sensor. In day-to-day use you rarely build a ticket from nothing: Response → Response actions holds a catalogue of named, reusable actions — “Isolate compromised workstation”, “Quarantine known-bad file” — each pre-configured with a type and its settings, so raising a ticket during an incident is choosing a host and pressing Run, not filling in a form under pressure.
| Type | Reaches a sensor ticket? | Config it needs |
|---|---|---|
isolate_endpoint | Yes — raises an isolate ticket. | Control-plane CIDR: the network the isolated host may still reach, so the sensor can keep reporting and the isolation can be lifted. Required; without it an isolated host cannot reach Qorionix and cannot be released. |
kill_process | Yes — raises a kill_process ticket. | Process name and/or PID. Leave both blank on the template and supply the PID when you run it. |
quarantine_file | Yes — raises a quarantine_file ticket. | The absolute file path on the host. |
block_ip | No. A perimeter action with a simulated executor, handled through the integration path rather than the sensor. | The IP address to block. Blocks that address for every host, not only the one you name when running it. |
custom | No executor at all — nothing runs on the sensor for this type. | An opaque JSON document handed to an integration as-is. |
If the target host has not checked in recently, Run still succeeds — the ticket is created and queued rather than refused — with a note that it will be delivered when the sensor next polls, and that it expires fifteen minutes after approval if the host does not come back in time by then. This is the console making visible a state that used to be invisible: an approved ticket simply waiting, silently, for a host that never came back.
Execution history: one word per run
Every time a catalogue action is run, it appears in Execution history with a state that collapses the ticket status and the target's online/offline fact into one word — friendlier to scan than the raw ticket vocabulary above, and it is what most people mean when they ask “did that action actually happen”.
| State shown | What it means |
|---|---|
| Needs approval | The action itself required an approval record and none was supplied when it ran — no ticket was raised at all. Run it again with a reason. |
| Awaiting approval | A ticket exists and is sitting in the human approval queue under Response → Tickets. |
| Queued for host | Approved, the sensor is online, and it will be collected on its next poll. |
| Pending — host offline | Approved, but the sensor has not checked in recently. Waits for the host; expires if it does not return within fifteen minutes of approval. |
| Running on host | The sensor collected the ticket and has not reported back yet. |
| Done / Failed / Rejected / Expired | Terminal. Failed, Rejected and Expired all offer Run again. |
Who can approve and who can act
Creating, approving and rejecting tickets all require the response-actions write permission. Un-isolating and undoing require the response-actions execute permission, which is a higher bar, and deliberately: each of those makes a host change state immediately rather than queueing a request for somebody else to approve.
In the default role set, an analyst holds execute — containing a host is the core analyst job — and a viewer holds only the read permissions. Roles and permissions has the full grants. If a call returns 403 with {"error":"insufficient permissions"}, that is the RBAC layer and not a licence problem.
What to do next
- If isolation is on your list of things you might one day do, read Isolating a machine before you need it. It is written for whoever makes that call.
- Read Live response and approval for how a ticket is signed and what is recorded.
- Decide now who in your organisation holds the execute permission, and make sure it is more than one person.