Operator Actions & Human Approval
Examples use the fictional Acme MSP / Acme Corp / Acme HQ world (one operator-org pattern that also fits internal IT and small teams). Hostnames like
acme-wks-01stand in for your endpoints. Portal URLs usehttps://portal.example.comas a stand-in.
Mutating work against Acme Corp endpoints lands on Actions. A human operator reviews the payload, Approves & runs or Rejects, and the timeline keeps the handoff.
FlowRMM keeps operators in control of consequential endpoint work. Human approval, command guardrails, and audit history make the action plane a practical safety layer rather than a black box.
1. Human-in-the-Loop (HITL) Workflow
When an operator or an automated script triggers a command on a remote device, the request is evaluated against the endpoint's security policy.
Action States
Restricted actions transition through the following states on the Actions page:
- PENDING: The action is queued and awaits operator review.
- APPROVED: An authorized operator approved the execution of the action.
- REJECTED: An operator rejected the execution, halting the flow.
- EXECUTED: The agent received the approval token, executed the command, and returned the result.
The Actions page is a review surface: a selectable queue on the left and a detail pane on the right for payload, execution output, and a linear audit timeline. Approve / Reject / Retry controls appear only in the detail pane and only for statuses that still need a decision. Creating a new action opens a side sheet so compose never competes with output.
Four-eyes and HITL self-elevate
Bounded action autonomy
Governance also owns Action autonomy and the Agentic Policy Builder. It can auto-approve and dispatch only explicitly selected action kinds, scoped to selected client environments (or Unassigned), with a low or medium risk ceiling and an optional expiry. High-risk actions always require a human approver. The policy is evaluated again immediately before dispatch, so an expired rule, revoked environment, or changed target scope fails closed and leaves the action undispatched. Every matched decision is attributed to governance:auto-approve in the action audit trail.
2. Policy-Based Guardrails
The GuardrailEnforcer evaluates all commands before they are queued or dispatched.
Allowed & Restricted Tools
Policies specify:
- AllowedTools: Commands or scripts that are pre-approved to run instantly (e.g.
Get-Service,df -h). - RestrictedTools: Commands that require operator approval (e.g.
Restart-AppPool,Stop-Service). - BlockedTools: Forbidden operations that will be instantly rejected on the server before an approval request is even minted (e.g.
rm -rf /or unauthorized binary executions).
MCP AI autonomy tiers
External AI agents connect through POST /api/v1/mcp and use the same operator_actions queue as human operators. For connection steps, API key roles, client configuration, and example workflows, see Agent Execution & Control.
| Tier | When it applies | MCP behavior |
|---|---|---|
auto |
Read-only allowlisted command on one device and token has actions.execute |
Creates, approves, executes, and returns a compact result (optional capped waitSeconds); full stdout/stderr is retrieved with get_action_logs; Risk low |
approve |
Mutating command, unclassified command, bulk target, or deploy_package |
Creates PENDING_APPROVAL action; portal Approve & run dispatches immediately; AI polls get_action_status (or short wait_for_action) |
block |
Matches forbidden pattern from policy or env FLOWRMM_MCP_COMMAND_POLICY |
Rejected before queueing |
Tenant policy inputs:
FLOWRMM_MCP_COMMAND_POLICYJSON env var (autoAllowPatterns,blockPatterns,bulkAutoThreshold)ForbiddenActions/AllowedToolsfrom agentic policies are merged into the MCP classifier
All MCP-initiated actions appear on the Actions page with RequestedBy: mcp:<actorId> for audit and human override.
Bulk selector approvals are immutable. Before the Actions item appears, FlowRMM resolves names to IDs, performs live endpoint preflight, applies operator scope and protected/exclusion controls, and freezes the exact device list. The approval hash includes the selector, selector/group revision, operation, parameters, and frozen IDs. Staged follow-on batches inherit that hash and may not re-resolve a client, site, static group, or dynamic group. Cancelling the bundle blocks future batches; already-dispatched work is retained in audit rather than hidden.
3. Autonomous Agentic Triage (EndpointAgent)
FlowRMM features an autonomous Agentic Triage Engine (EndpointAgent) that monitors endpoints, identifies state anomalies, and formulates mitigation plans using local Large Language Models (LLMs), subject to strict policy guardrails and human verification.
1. Observe-Reason-Act Lifecycle
- Observe: Telemetry anomalies or security events are ingested. The agent is initialized with an
AgenticPolicymatching the endpoint's group scope. - Reason: When an LLM reasoning endpoint is configured via
LLM_URL, the engine sends the telemetry to it; with no endpoint configured the engine proposes no action (returns null) and the operator stays fully in control. The LLM compares the active telemetry against theDesiredStatenatural language policy and proposes a structured JSON action:
{
"ActionName": "Stop-Service",
"Target": "spooler",
"Parameters": { "Name": "spooler" },
"Reasoning": "Print spooler is exhibiting abnormal resource usage, stopping it to restore system stability."
}
- Validate: Before the action is presented to a human operator, the
GuardrailEnforcerevaluates it.
2. Strict Guardrail Verification
The GuardrailEnforcer evaluates the LLM's proposal against the policy definitions:
- ForbiddenActions: If the proposed command or parameters match any forbidden pattern (e.g.
rm -rfor specific destructive cmdlets), it throws anEscalationExceptionand registers aguardrail_rejectedaudit log. - AllowedTools Allowlist: If
AllowedToolsis populated, the command *must* match one of the allowed tool names; otherwise, it is blocked. - Queueing for Approval: If the proposal passes all guardrails, the engine creates a
PendingActioninPENDINGstate and logs anapproval_requestedevent.
3. Human-in-the-Loop Execution
- Operators inspect pending agentic triage proposals via
GET /api/v1/operator/agentic/actions(bearer +agentic.actions.read,monitor.read, orportal.read) or the unified Actions page. - If approved (
POST /api/v1/operator/agentic/actions/{id}/approve), the action transitions toAPPROVEDwith the operator's actor ID. - Executing the action (
POST /api/v1/operator/agentic/actions/{id}/execute) dispatches the command to the target C# agent, records the output, and sets the status toEXECUTED.
4. Unified Action Plane & Audit Logging
Every operation dispatched to endpoints is processed through a unified action plane defined in operator-actions.ts:
- Portal session:
GET/POST /api/v1/actions(browser-authenticated operators). - Bearer automation:
GET/POST /api/v1/operator/actions(requiresactions.read,actions.write, andactions.executeas appropriate). - Action Kinds:
run_command: Directly executes inline commands or scripts.run_script: Executes saved runbooks byscriptId.install_package: Installs apps via package managers (winget, Chocolatey, Homebrew, orapt) with optional version/source fields, provider-specific install arguments, and policy-controlled prerequisite bootstrap for Chocolatey/Homebrew. Winget installs defaultallowVendorMsiFallback: trueso allowlisted packages (for exampleGoogle.Chrome) can recover from admin hash-mismatch via a known vendor MSI + verifiedmsiexecwait.remote_input: Simulates user mouse and keyboard inputs during fallback streams.collect_evidence: Gathers diagnostic details from endpoints.reboot_device: Human-only reboot action that dispatches a dedicated monitorkind: "reboot"command. AI and automation paths must not create this action kind. Operators can also reboot from the Remote workspace toolbar or from the endpoint Security/Patches drawer tab when patch telemetry reports a pending reboot.
- Risk Tiers: Actions are classified by risk levels (
low,medium,high) which dictate whether instant dispatch is allowed or if human approval is mandatory. - Durable Audit Logs: Every action, whether executed instantly, approved, or blocked, is recorded in the immutable audit trail:
- Logs include the requesting actor ID, the approving operator ID, target device ID, command string, execution status, and timestamp.
- Blocked actions create a specific
approval_rejectedorguardrail_blockedaudit record with enforcer diagnostics.