Closes the agent-module coverage gap the reconciler flagged (activeteller + 14). Grounded per module in hiveops-agent/hiveops-module-*; audience dev (dev-only). Reconciler now green. Grounding surfaced agent-side bugs (log-error route mismatch, atec poll-interval hardcoded) — to verify + file next. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6.1 KiB
module, title, tab, order, audience
| module | title | tab | order | audience |
|---|---|---|---|---|
| agent.remote | Remote Control Module — on-demand screen capture & file access on ATMs | Internal | 20 | dev |
Internal · ops/support view. Confirmed against
hiveops-module-remotesource (RemoteModule, agent parent v4.4.3) on 2026-07-01.
What it does (and doesn't)
hiveops-module-remote (module name hiveops-remote, class com.hiveops.remote.module.RemoteModule) is not a monitor and does not emit incident/journal events. It is an on-demand remote-control executor. It sits idle, registers with the HiveIQ Remote server (hiveops-remote, internal port 8090), long-polls it for a single queued command, executes it, and uploads the binary result back. There is no continuous monitoring, no baseline, and no IAT_* / EventType reporting from this module.
Supported commands (the module's advertised capabilities):
| Capability | What the agent does |
|---|---|
SCREENSHOT |
Captures the ATM's display via AWT Robot, encodes JPEG, uploads bytes in chunks |
FILE_LIST |
Lists a directory (name, size, mtime, type, POSIX perms) and returns JSON |
FILE_DOWNLOAD |
Streams a single file's bytes back in chunks |
SYSTEM_INFO exists in the CommandType enum but is not advertised as a capability and is not handled — if the server ever sends it the agent replies FAILED: Unknown command type.
Flow at a glance:
- On
start(), the modulePOSTs to/api/v1/agents/registeron the remote server and stores the returned Bearer token. - It polls
GET /api/v1/agents/pollevery 5s (remote.poll.interval.ms). - When
hasCommand=true, it sets the commandIN_PROGRESS, runs it, then reportsCOMPLETED(with result/binary) orFAILED. - Binary results (screenshot JPEG, file bytes) are uploaded in 1 MiB chunks with a per-chunk SHA-256 checksum to
POST /api/v1/agents/commands/{id}/upload.
This module talks to the hiveops-remote service (
/api/remote/, port 8090) — not to agent-proxy or hiveops-incident. It is a separate path from the standard journal/event pipeline.
Config properties it registers
Registered in getDefaultConfiguration() (namespace remote.*):
| Key | Default | Meaning |
|---|---|---|
remote.enabled |
false |
Master on/off. Module only loads when true. |
remote.server.url |
http://localhost:8090 |
Remote-server base URL. Required — init throws if blank. |
remote.poll.interval.ms |
5000 |
Delay between polls for a queued command. |
remote.poll.timeout.ms |
15000 |
Registered default, but not referenced anywhere in code (no effect — unverified whether wired in a newer build). |
remote.chunk.size.bytes |
1048576 |
Upload chunk size (1 MiB) for binary results. |
remote.max.file.size.bytes |
104857600 |
Max file size (100 MiB) for FILE_DOWNLOAD; larger files fail. |
Also read at init but not in the defaults set (must be added explicitly to take effect):
| Key | Default if unset | Meaning |
|---|---|---|
remote.machine.id |
derived from hostname (then random UUID) | Stable machine identity sent at registration. |
remote.allowed.paths |
(empty = all paths allowed) | Comma/semicolon list; if set, file ops are restricted to these base dirs. |
remote.blocked.paths |
OS default block list | Comma/semicolon list of blocked path patterns (* wildcard). Defaults block /etc/shadow, /etc/passwd, /etc/sudoers, /root/.ssh, /home/*/.ssh (Linux) and C:\Windows\System32\config, ...\drivers, credential stores (Windows). |
Enabled / deployed to ATMs
- Enable condition: module self-enables only when
remote.enabled=true. It is off by default. Turn it on for a device/institution with aCONFIG_UPDATEfleet task settingremote.enabled=true(and, on locked-down ATMs,remote.allowed.paths). - Shipped how: it's a drop-in JAR (
modules/hiveops-module-remote.jar), not baked into the fat JAR. Jackson is shaded into the JAR (hiveops-core isprovided). - Retrofitting an ATM that doesn't have the JAR: deliver via a fleet
INSTALL_MODULEtask — it drops the JAR intomodules/and restarts the agent (ProcessInstallModule). The filename must end in.jar.
Common failure modes / what to check
| Symptom | Likely cause | What to check |
|---|---|---|
| Module never registers / no commands run | remote.enabled not true, or module JAR absent |
Confirm remote.enabled=true and that modules/hiveops-module-remote.jar is present; check agent log for Initializing remote module for server: ... |
Init fails: remote.server.url is required |
Property blank/missing | Set remote.server.url to the remote server (prod path is via /api/remote/, internal :8090). |
Registration logs Failed to register with remote server |
Server unreachable / auth rejected | Registration errors are swallowed (no retry loop) — the module keeps polling with a null token, so polls 401. Verify network path to the remote server and that it accepts the registration payload. |
SCREENSHOT fails: Screen capture not available in headless mode |
ATM/JVM is headless (no X display / service session) | Screen capture needs a real graphics environment + AWT Robot. Headless Linux boxes and some Windows service sessions can't capture. |
FILE_DOWNLOAD fails: File exceeds maximum size limit |
File > remote.max.file.size.bytes (100 MiB default) |
Raise the limit via config, or collect large files with a fleet FILECOLLECT/LOG_COLLECT task instead. |
File op fails: Access to path is blocked / Path is not within allowed directories |
Hit a remote.blocked.paths pattern, or path is outside remote.allowed.paths |
Expected security behavior — adjust the allow/block lists if the target should be reachable. |
File op fails: Path contains directory traversal sequences / null bytes |
Path contained .. or \0 |
Path-traversal guard (PathSecurityUtils) — send a normalized absolute path. |
| Upload fails mid-transfer | Network drop, or server rejected a chunk (checksum/size) | Uploads are not retried by this module — the command goes FAILED. Re-issue the command. |