Open Manage tatersecurity.com

Interactive Remote Control - ATO Compliance Reference

NIST 800-53 control mapping, configuration model, and audit-trail reference for TATER's interactive remote control feature. Designed for inclusion in FedRAMP Moderate / DoD IL4 authorization packages and SOC 2 / ISO 27001 audit evidence.

Overview

TATER's interactive remote control feature lets a SuperAdmin or Admin user start a real-time WebRTC session to a managed endpoint. Phase 2 (shipped 2026-05-07) adds end-user consent prompts (PE-3), mouse/keyboard input injection, bidirectional clipboard sharing, multi-monitor selection, and session recording (AU-14) on top of the original view-only baseline. Capabilities are individually toggleable per session. A session that requests input injection, clipboard, file transfer or recording is gated on a 30-second fail-closed end-user consent dialog; a view-only session raises no prompt, so screen observation alone is not gated on the end user's agreement. Where no user is logged on at all, consent cannot be obtained by any mechanism — see Unattended Sessions for the compensating controls that apply in its place. Phase 2.1 will add file transfer, H.264/VP8 video encoding, private TURN relay support, and Wayland (Linux) input injection.

Revision note - 2026-08-11

This revision corrects a number of control statements that this page previously made and the shipped code did not support, and adds the Unattended Sessions section. Several controls are now recorded as partially met with the gap named. If you have already cited an earlier revision of this page in an SSP, a SOC 2 or ISO 27001 evidence package, or a customer questionnaire, re-read the AC-17(3), AC-17(9), AC-2/AC-3/AC-6, AU-2/AU-12, AU-14, CM-7 and PE-3 rows below before relying on that citation.

NIST 800-53 Control Mapping

The feature implements the following controls. Cite this section in the System Security Plan (SSP) and continuous monitoring artifacts.

ControlImplementationEvidence Location
AC-17 Remote Access Three-layer gating: (1) org master switch in TATER Manage → Devices → Remote Control Org Policy card; (2) per-device opt-in, enforced server-side at both session-create and session-discovery; (3) role gate - SuperAdmin, Admin/OrgAdmin or ServiceProvider (see AC-2/AC-3/AC-6). All three must be true. A device may additionally veto locally with remoteControlDisabled: true in its agent config; the agent reads that key on every remote-control path, but no supported tool writes it, so applying the veto is a manual per-endpoint edit - see Step 2. Org switch: Settings.remoteControlEnabled. Per-device: Settings.remoteControlDeviceIds / Settings.remoteControlAllDevices. Role: JWT validated by auth.ts.
AC-17(2) Cryptographic Protection Mandatory DTLS encryption via WebRTC. The signaling layer (offer/answer/ICE) routes through the TATER API over HTTPS; the media plane is direct peer-to-peer with DTLS keying. Plaintext frames never traverse the wire. Pion/webrtc v4 enforces DTLS by protocol. Correction: the DTLS key fingerprint is not recorded in the audit log. It is carried in the SDP that the signaling routes relay, and those routes emit no audit entries at all (see AU-2/AU-12), so no fingerprint is retained anywhere. Evidence for this control is the protocol guarantee, not a per-session record.
AC-17(3) Managed Access Control Points Signaling traffic is relayed only through TATER's API endpoints (POST /api/agents/{id}/rtc/sessions for create; POST /signal for offer/answer/ICE). The agent attaches only to sessions returned by its own authenticated poll, never to arbitrary IDs. Correction: session IDs are not signed. They are rtc- plus 16 hexadecimal characters (8 random bytes, 64 bits of entropy) and carry no signature or MAC. They are identifiers, not bearer credentials: every signaling and lifecycle route independently requires an authenticated caller (an Admin JWT or an organization-bound API key) and resolves the session inside that caller's own tenant and organization, so possession of an ID alone reaches nothing. API request logs. Cosmos AgentRtcSessions container. ID generation: agentRtcSessions.tscreateRtcSession.
AC-17(9) Disconnect / Disable Access Partially met - enforcement is agent-side only. Default maxSessionMinutes: 30 (the server clamps the caller's value to 1–240) and idleTimeoutMinutes: 10 (clamped to 1–60); those clamps validate the value at session-create, they do not enforce elapsed time. Elapsed time is enforced by the agent's own runner loop (enforceTimeouts, evaluated every 5 seconds), which tears down the peer connection and PATCHes the session to TimedOut. An Admin can end any session manually, and the agent can refuse or terminate. There is no server-side reaper or timer for AgentRtcSessions. If the agent process stops - crash, reboot, service stop, auto-update binary swap - the media plane dies with it, but nothing on the server terminates the record: the session document stays in a non-terminal state until its 30-day Cosmos TTL removes it, and the one-active-session-per-device guard will refuse a new session for that device (HTTP 409 SESSION_ALREADY_ACTIVE) until an Admin ends the stale one by hand. Compare agentCommandReaperTimer, which performs exactly this function for agent commands and ops jobs. Carried as a gap; server-side reaping is scheduled with Phase 2.1. Session record's maxSessionMinutes, idleTimeoutMinutes, endedAt, endReason. Agent enforcement: internal/remotecontrolenforceTimeouts.
AC-2 / AC-3 / AC-6 Authorization Partially met. A role check via authorize(user, ['Admin']) runs on the JWT-authenticated routes: session create, per-device session list, active-session list, and recording playback. Two qualifications an assessor needs: (1) ServiceProvider does satisfy an Admin check - authorize() grants Admin-level access to a caller whose role in the selected organization is ServiceProvider, and its role map lists Admin among the roles ServiceProvider is granted. So access is SuperAdmin (cross-org), OrgAdmin / Admin (org-scoped) and ServiceProvider (for assigned client orgs). Auditor and Viewer do not have access. (2) The routes that also accept an agent's x-api-key - PATCH state transition, POST and GET signal, DELETE, POST recording frame - apply no role check on that branch: the key is authenticated and must be bound to an organization, but an API key carries no role. Any organization-bound API key for that org can therefore transition, signal on, or end any session in the organization. Treat agent API keys as session-control credentials and scope them accordingly. Auth middleware in auth.ts (authorize(), role map); HTTP 403 on insufficient role. API-key branch: validateApiKey result carries tenantId / organizationId and no role.
AU-2 / AU-12 Audit Events Partially met. Audit-logged: session create; every state change made through PATCH /sessions/{id} (including the PE-3 consent decision, granted or denied, and a dedicated recording-started entry); and session end via DELETE. Each entry captures admin oid, deviceId, hostname, transition, duration, end reason, and the ATO flag set. Three gaps: (a) the automatic Pending → Negotiating transition is performed by the signaling route when the first offer or answer arrives and writes no audit entry, so that one transition is absent from the trail; (b) signal relay itself (GET / POST .../signal) is not audited; (c) recording playback (GET .../recording) is not audited - an Admin can replay a recorded session without leaving any record that they did. Do not represent the Activity Log as a complete record of who has viewed a session recording. TATER Activity Log filtered by entityType=AgentRtcSession.
AU-14 Session Audit Session recording at ~0.5 fps (every 10th frame at the default 5 fps capture rate). JPEG frames are uploaded to the API as base64 and written as-is to the Cosmos AgentRtcRecordingFrames container, partitioned by tenant, with a 30-day TTL. Playback timeline available in the Manage UI → Devices → Recording; recording start fires a dedicated recording-started audit log entry. Optional and off by default for attended sessions; required for unattended sessions (see Unattended Sessions). Correction on encryption: there is no application-layer encryption of frame data. Confidentiality at rest rests on the Azure Cosmos DB service's own encryption with Microsoft-managed keys; in transit it rests on TLS to the API and DTLS on the media plane. Any principal holding read access to that container reads the frames directly. Playback is not itself audit-logged - see AU-2/AU-12. Phase 2 (shipped). Schema: recordingEnabled, recordingFrameCount; frame documents carry jpegBase64 in cleartext base64.
CM-7 Least Functionality Off by default at every level. The org master switch defaults to false. Per-device authorization is a server-side allowlist that defaults to empty (remoteControlAllDevices: false, remoteControlDeviceIds: []); an org with no Settings document resolves to all-off. Input injection, clipboard, and recording are individually toggleable per session and all default to false unless the admin explicitly enables them at session start. On consent, three cases must be distinguished: for an attended session, enabling any of input / clipboard / file transfer / recording raises the PE-3 prompt and the session does not proceed without a grant; a view-only session raises no prompt at all; and for an unattended session no prompt is possible, so the compensating controls in Unattended Sessions apply instead - including that recording is not optional there. Server-side defaults in the org Settings document, read by agentRtcSessions.tsgetRcPolicy. No longer config.go: ADO #2014 (commit e942f958) moved the per-device decision server-side, and the agent's legacy config.json remoteControlEnabled key is retired as a gate - it is not evidence for this control.
PE-3 Physical Access — User Consent (attended sessions) The agent displays a native consent dialog on the endpoint listing every capability the admin requested (view, input, clipboard, recording) and the admin's identity. The user must Allow within 30 seconds - no response or Deny is treated as fail-closed (denied). Implementations: PowerShell System.Windows.Forms.MessageBox on Windows, osascript display dialog on macOS, zenity / kdialog / xmessage on Linux. Both grant and deny outcomes (explicit refusal and timeout alike) fire dedicated audit log entries. Scope qualification: the prompt is raised only when the session requests input injection, clipboard, file transfer or recording. A session requesting none of those - view-only - proceeds without prompting, so observation of the endpoint's screen is not itself consented to. State that explicitly wherever this control is claimed. Phase 2 (shipped). Schema fields: consentObtainedAt, consentMethod (in-session-prompt / timeout-denied / unattended-no-user, the last of which is never a grant - see the row below). Audit-log events consent-granted / consent-denied.
PE-3 Physical Access — unattended sessions (no logged-on user) Not met by consent, and cannot be. Where no user is logged on there is no party to prompt, so end-user consent is not merely skipped as a matter of configuration - it is structurally impossible. No dialog, timeout, or default value can produce a consent decision from an absent party, and an unattended session must therefore never inherit a "consent obtained" posture. Four compensating controls apply in its place: the session is marked UNATTENDED distinctly in both the session record and the audit log; session recording is required rather than optional (AU-14); an explicit operator acknowledgement is required at session-create, naming what is being authorised; and org administrators are notified out of band that an unattended session occurred. See Unattended Sessions for the full statement and for current implementation status. An unattended session must never be represented in an SSP or an audit as a consented session. Met by compensating control, not by consent - see Unattended Sessions. Session record carries unattended: true, operatorAckAt / operatorAckText, and consentMethod: unattended-no-user; consentObtainedAt is never set, and the server strips it if an agent sends one. Recording is forced on. Audit event: unattended-session-started.
IA-2 / IA-2(1) Identification & Authentication, MFA MFA is enforced at the TATER application layer via Microsoft Entra ID Conditional Access. Admin role assignment + MFA-protected sign-in are prerequisites for any session creation. Entra ID CA policies (customer-controlled). Audit log entries include the admin's authenticated oid.
AT-3 Role-Based Training This documentation page surfaces the audit trail format and operational behavior for privileged users. Customers should reference it in their internal training program. This page + Activity Log filter walkthrough.

Enabling Remote Control for Your Organization

Step 1 - Org Master Switch

SuperAdmin or Admin opens TATER Manage → Devices. The "Remote Control Org Policy" card at the top shows the current state. Click Enable; confirm the dialog. The toggle persists in Settings Cosmos doc as remoteControlEnabled: true. This is your AC-17 / CM-7 master switch.

Step 2 - Per-Device Opt-In

Per-device authorization is held server-side, in the same org Settings document as the master switch. Nominate the endpoints that may accept sessions:

{
  "remoteControlEnabled": true,
  "remoteControlAllDevices": false,
  "remoteControlDeviceIds": ["cb-imgsvr-99k", "x1-22-2025-08"]
}

Device IDs are matched case-insensitively. Set remoteControlAllDevices: true to authorize the whole fleet instead of maintaining a list. The check runs at both session-create and on every agent discovery poll, so removing a device immediately stops new sessions being created for it and stops it claiming a session that was created before the revocation but not yet picked up.

Revocation does not tear down a session that is already running. The signaling, state-transition, end and recording-upload routes do not re-check the per-device policy, and the agent's poll loop does not terminate sessions it has already attached to - so a connected session survives revocation until it is ended explicitly or hits its idle / max-duration cap. To stop a session in progress, end that session (Manage → Devices, or DELETE /api/agents/rtc/sessions/{id}); removing the device from the allowlist alone is not sufficient.

No agent-side change or restart is required, and nothing needs to be edited on the endpoint.

Changed in ADO #2014 (commit e942f958). This layer previously lived in the agent's own config.json as remoteControlEnabled: true. Nothing in the product ever wrote that key - a tree-wide search finds readers and no writers - and this page instructed administrators to hand-edit it on every endpoint, so the gate could not be satisfied by any supported path and blocked remote control on every device in the fleet. Moving the decision server-side makes it settable, auditable and centrally revocable, and is strictly stronger: an agent can only host a session the server already authorized, so it cannot self-authorize.

Two different settings share the name remoteControlEnabled. The live one is Settings.remoteControlEnabled in the org's Cosmos Settings document - the AC-17 org master switch of Step 1. The retired one is remoteControlEnabled in the agent's local config.json; it is still parsed for backward compatibility but is no longer consulted to enable anything. When reading a configuration dump, an older runbook or a prior revision of this page, check which document is being described - the two are unrelated and only one of them does anything.

The local veto, and what applying it actually involves. To hard-disable one machine regardless of server policy, set remoteControlDisabled: true in that agent's config.json; the agent reads it on every remote-control path and it wins over server policy. Two corrections to what this page previously said. First, config.json is not an encrypted file: it is plain JSON written mode 0600 in the agent's data directory, in which only secret fields - the API key and any share credentials - are DPAPI-wrapped on Windows, so it can be edited by hand with local administrator rights on the endpoint. Second, no supported tool, installer property, CLI flag or server policy writes remoteControlDisabled: it has readers and no writers, which is the same shape as the gate this change removed. Treat the local veto as a manual, per-endpoint action rather than a managed control, and prefer removing the device from remoteControlDeviceIds wherever central revocation will do.

Step 3 - Starting a Session

In TATER Manage → Devices, click the 🖥 Remote button on any device row. Configure session limits in the modal (max minutes, idle timeout). Click Start Session. The agent will receive the request, open a Pion/webrtc peer connection, and start streaming JPEG frames at 5 fps over the data channel. The admin browser displays them on a canvas element.

Auditing Sessions

Every session lifecycle event is logged. To audit:

  1. Open TATER → Activity Log
  2. Filter by entityType=AgentRtcSession
  3. Each entry shows: who created, which device, state transitions, total duration, end reason
  4. For SIEM forwarding, ensure your TATER SIEM integration is configured (Settings → SIEM); session events propagate via the standard CEF/webhook channel
  5. Account for the gaps recorded under AU-2 / AU-12 above: the automatic Pending → Negotiating transition, signal relay, and recording playback produce no Activity Log entry. Reconstructing a session timeline from the Activity Log alone will be missing those events, and the log will not tell you who replayed a recording.

Unattended Sessions

An unattended session is a remote control session to an endpoint where no interactive user is logged on - a headless image server sitting at its logon screen, a kiosk, a machine that has rebooted and is waiting at Winlogon. TATER supports this case on Windows: the agent service relaunches itself into the console session and attaches to whichever desktop currently owns input, so the operator sees and can drive the secure (Winlogon) desktop. The mechanism, and the fact that it is a more powerful primitive than the tray path it replaces, is described under Security Considerations.

The consequence for PE-3 is not a matter of configuration or policy preference. End-user consent is structurally impossible for an unattended session: there is no user present to ask. No dialog, no timeout, and no default value can produce a consent decision from an absent party. It follows that an unattended session must never silently inherit a "consent obtained" posture, and must never be conflated in an audit with a session to which a user actually agreed.

Four compensating controls apply in place of PE-3 consent. They are requirements of the unattended path, not per-session options:

  1. The session is marked UNATTENDED distinctly - in the session record (unattended: true, consentMethod: unattended-no-user, with consentObtainedAt left unset) and in the audit log entry. An unattended session and a consented session are separable in every query an assessor will run, and neither can be mistaken for the other.
  2. Session recording is required (AU-14), not per-session optional. An unattended session that cannot record does not start. The recording is the substitute witness for the absent user, and it is the only contemporaneous account of what was done on the endpoint.
  3. An explicit operator acknowledgement is required at session-create, naming what is being authorised: the device, the capabilities requested, the absence of an end user, and that the session will be recorded. The acknowledgement is stored on the session record and reproduced in the audit entry, so the authorisation is attributable to a named operator rather than implied by the session's existence.
  4. Org administrators are notified out of band that an unattended session occurred, through a channel the operator does not control, so the operator is not the only witness to their own session.

Control 2 inherits the AU-14 limits recorded above: frames are stored without application-layer encryption, and playback is not itself audit-logged. Both matter more here than in the attended case, because for an unattended session the recording is the primary evidence rather than a supplement to a user's recorded decision.

Implementation status - read before citing this section

The unattended capability is real and shipping. Measured on CB-IMGSVR-99K on 2026-08-11 under ADO #2014: a session-retargeted SYSTEM helper captured and drove session 1's Winlogon secure desktop while its parent ran in session 0, at the display's native 2560×1440.

The four compensating controls are enforced in code as of this revision. The session record carries unattended, operatorAckAt (stamped from the server clock, never from the request) and operatorAckText; recordingEnabled is forced to true for an unattended session and cannot be turned off by the caller or by any later PATCH; a distinct unattended-session-started audit entry is written at create; and org administrators are notified out of band through the standard notification hub, on an event identifier that is not org-configurable and therefore cannot be switched off in Settings.

The endpoint, not the server, is the authority on whether anybody is actually logged on - unattended is only ever an operator declaration. The agent reconciles the two before a session starts, and the reconciliation is deliberately asymmetric: a session declared unattended that arrives at a machine where someone is signed in falls back to the ordinary consent prompt, and a session not declared unattended that arrives at a machine with nobody signed in is refused rather than run. That second rule is what stops an unattended session happening by accident, without the acknowledgement, the forced recording or the notification.

Two limits to state plainly. First, no interface currently sends unattended: the Manage session-create dialog does not offer it, so an unattended session can at present only be created through the API directly. Second, the AU-14 recording-started audit entry fires at consent-grant time, and an unattended session has no consent grant - so recording being forced on is evidenced by the create-time record and the stored frames, not by a separate start event. Both are tracked on ADO #2014.

PE-3 for unattended sessions should be recorded as met by compensating control, not by end-user consent, citing this section. Assessors who need the underlying evidence should pull the unattended-session-started audit entries for the period under review, each of which carries the operator's acknowledgement text verbatim alongside the device and the authorising administrator.

Phase 2 (Shipped 2026-05-07)

  • End-user consent prompt - PE-3 / HIPAA / CMMC Level 3. Native dialog on the endpoint with 30-second fail-closed timeout. Capability list and admin identity displayed. Raised for attended sessions that request more than view-only; not raised for a view-only session, and not possible at all for an unattended one (see Unattended Sessions).
  • Mouse/keyboard input injection - Native Win32 SendInput on Windows (no CGO), xdotool shell-out on Linux X11, cliclick / osascript on macOS. Coordinates normalized 0–1 over the wire and denormalized at the agent against the selected monitor's bounds.
  • Clipboard sharing - Bidirectional via dedicated clipboard data channel. PowerShell Get-Clipboard/Set-Clipboard on Windows, pbcopy/pbpaste on macOS, xclip/xsel on Linux. Gated on a separate consent prompt and toggleable per session.
  • Session recording (AU-14) - ~0.5 fps sampled JPEG frames, 30-day TTL, in-app playback timeline with frame scrubber. Frames are stored as cleartext base64 in Cosmos and rely on the platform's service-level encryption at rest, not on application-layer encryption; playback is not audit-logged. See the AU-14 and AU-2/AU-12 rows.
  • Multi-monitor selection - Display picker in the admin modal. Capture by index using kbinani/screenshot's GetDisplayBounds; supports any number of attached displays.

Phase 2.1 Deferred

  • File transfer - bounded by max-size and per-direction consent.
  • H.264/VP8 video encoding - replaces the JPEG-over-data-channel placeholder for higher quality at lower bandwidth (target: 30 fps at 2–4 Mbps).
  • Wayland input injection (Linux) - ydotool integration with build-time selector; current Phase 2 only supports X11.
  • macOS scroll & alpha-key codes - cliclick doesn't emit scroll events natively; AppleScript keystroke covers letters/digits but key-code map is small.
  • Private TURN relay - for federal customers requiring all media to traverse a sanctioned VPN.

See INTERACTIVE-REMOTE-CONTROL-PLAN.md for the full multi-week scoping document.

Security Considerations

  • STUN servers - the agent uses Google's public STUN servers for NAT discovery. STUN does not carry media; only NAT-traversal candidates. Private TURN relay, for customers who require all media to traverse a sanctioned network, is deferred to Phase 2.1 and is not available today.
  • SDP fingerprint validation - DTLS keying material is exchanged via signaling. The TATER API relays signaling messages but does not interpret them; man-in-the-middle attacks are mitigated by the API's TLS layer.
  • Windows session isolation and the session-retargeted SYSTEM helper - the agent service runs in session 0. Window stations and desktops are per-session objects whose names resolve in the caller's session, so a service that opens "the desktop" opens session 0's, which is genuinely empty; two probes under ADO #2014 captured that desktop and reported an all-black frame with every success signal green. Earlier revisions of this page stated that the agent therefore skips remote control in Windows service mode and that a tray-mode binary in the user session is required. That is no longer how it works, and the tray requirement made the feature structurally impossible on exactly the machines that most need it - the tray is launched from the MSI's HKLM Run value at user logon, so a server nobody signs into never has one. The service now supervises rather than captures: when the API reports an authorized session for the device, it relaunches the same signed binary into the console session, attached to whichever desktop currently owns input, using a token manufactured from its own SYSTEM token (DuplicateTokenExSeTcbPrivilegeSetTokenInformation(TokenSessionId)CreateProcessAsUser). Assess this as a more powerful primitive than the tray path it replaces, not as an extension of it: the result is a SYSTEM process on the secure desktop, able to observe and inject input at the logon screen, where the tray was a user-context process confined to that user's own desktop. Its scope is bounded accordingly - it is spawned only for a session the server has already authorized, one instance per session, and it exits once no authorized session has justified it for five minutes, so a SYSTEM process on the logon desktop does not outlive the authorization that created it.
  • Session ID guessing - session IDs are rtc- plus 16 hexadecimal characters (8 random bytes, 64 bits) and are not signed; a prior revision of this page described them as signed and as 32 hex characters, and both were wrong. They are identifiers rather than credentials: every route that accepts one still requires an authenticated caller and resolves the session within that caller's own tenant and organization, so guessing an ID does not by itself reach a session. The agent only attaches to sessions returned by its authenticated API call, not arbitrary IDs.

See also: Settings Reference, Agent Deployment, GRC Modules Guide.