RemotePower 8.0.0: ten setup wizards and a security review that fixed 19 findings
RemotePower 8.0.0 is out. It is the first release of a new major version, published on 11 November, and it comes with ten setup wizards, a text size that goes up to 300% and fixes for 19 findings from a security review,
RemotePower 8.0.0 is out. It is the first release of a new major version, published on 11 November, and it comes with ten setup wizards, a text size that goes up to 300% and fixes for 19 findings from a security review, one of them rated High. Every release gets a codename ending in "Matters"; this one is Pil0tMatters.
If you haven't met RemotePower yet, it is a self-hosted tool for monitoring and managing a fleet of Linux, Windows and macOS hosts. A server and a small agent on each host give you a web UI with monitoring and alerting, a CMDB, CVE scanning, patching, compliance reports, a helpdesk and remote access. The agents poll outbound only, so nothing listens on the managed host. It started as a web page with one button that shut a machine down, which I wrote in Python one afternoon. Scope creep did the rest, and these days Claude Code writes most of the code while I decide what goes in. It is MIT licensed.
Setup wizards
Several things in RemotePower take more than one screen to set up, and 8.0.0 adds a guided setup for ten of them, usually behind a Guide me button: a host, a notification destination, an integration, e-mail, single sign-on, receiving syslog, receiving network flows, a relay satellite or scan worker, the agent push channel and the SSH gateway.
The OIDC card is seven boxes, and what goes in them depends on what you created in your identity provider. E-mail is switched on per event, so a form that is filled in and tested can still send nothing. A wizard asks for one thing at a time, in the order the work happens, and checks as it goes. The dialogs it sits next to are still there, and nothing changes until you press a button.
The host wizard waits for the host to check in and then shows what it got: name, group, tags, OS and address. Before anything real goes out, the notification wizard saves the destination switched off, sends one message and shows the answer, with the status code and what it usually means when delivery failed. E-mail and sign-on are tested with the settings you typed, before anything is saved, so a wrong password or port never replaces settings that work. The push wizard won't continue until the push daemon answers, and the SSH gateway wizard waits for the gateway service to connect.
The sign-on guide knows the quirks of Authentik, Authelia, Keycloak, Pocket ID and Zitadel. Zitadel, for example, sends no groups claim by itself, so everyone stays a viewer until an Action adds one, and the guide says so on the step where you register the client.
The e-mail, sign-on and integration wizards save only on their last button, so closing one halfway changes nothing. Six long dialogs (maintenance window, monitor target, backup job, auto-patch policy, rollout and host profile) also got a Step by step switch that shows the same form a few fields at a time, says at each step what the form would refuse at the end, and finishes on a review of your choices.
Testing the wizards and the step-by-step form turned up two bugs. One was an old bug in the New backup job dialog. It remembered which hosts you had ticked, but its save read only the boxes on screen, so a host you had ticked and then filtered out of the list was left out of the job without a word. The other showed only when you typed fast. A wizard moved the focus to its first box a frame after it drew a step, and keystrokes for a box you had just chosen landed in the wrong one. That happened in 12 of 120 tries on a loaded machine and in none of 200 after the fix.
Escape closes a wizard and returns the focus to where it was, Tab stays inside the dialog, every step is announced by name, and Ctrl or Cmd with Enter presses the primary button.
The interface
Text size now runs from 80% to 300% in ten steps, from the user menu or under My Account β Appearance. A window that is too narrow for a step holds the largest ones back: 200% at most on a window 1,440 pixels wide and 110% on a phone. A dialog still fits the window at 300%, and a menu opens next to its button.
Thirteen more pages, among them Server Status, Patches, Tickets and Containers, show one group at a time as tabs. If you prefer the long scroll, choose One long page under My Account β Appearance β Page sections; the choice is kept in your browser.
Home keeps up to eight named layouts. You can start one from a copy, from an empty page or from one of four ready-made ones (Fleet overview, Security, Patching and Capacity), and a wall display link cycles through them. Smaller changes include a heading on every page for screen readers, controls at least 24 pixels across, and cron schedules written out as sentences.
Apps, monitors and connectors
- App discovery. The Linux agent reads listening sockets, containers and running services and says which of 63 well-known apps it found. Each one gets Monitor and Connect buttons, and Connect opens the integration wizard with the address and port filled in. Nothing is probed.
- Handshake monitors. SMTP, IMAP, SSH banner and NTP monitors check that a service answers as it should: the greeting, the server's abilities, an encrypted session, the clock's offset. They send no mail and log nobody in, and they run from the server, a Linux host's agent or a satellite.
- Connectors. Tailscale, Headscale and Cloudflare Tunnel are new, Apprise is a destination of its own, and several existing connectors (Pi-hole, Immich, Proxmox Backup Server, UniFi) read more of what their products report.
-
A read-only MCP endpoint.
POST /api/mcpspeaks the Model Context Protocol from the server itself, so a client that can send a header connects without a local file. It offers 16 read tools, and every call runs as the API key that made it, so that key's scope, addresses, expiry and rate limit apply. - Image updates with a rollback. The Image updates tab can update the images you list, in shadow mode first, where it records what it would do and queues nothing. An option rolls a project back to its previous images when the check after an update finds an unhealthy container.
-
Traffic. Each Linux agent reads its established TCP connections with
ssonce a minute by default, and Threat Intel shows which addresses each host talks to, which programs open the connections and how much each moved. A watch list raises an alert on a match. -
Detections. A sweep every five minutes runs six rules over what the agents already send, such as a shell or
ncholding a connection to a public address, or a new SSH key followed by a new destination. Each finding raises one alert, so it can be acknowledged, muted and routed like any other.
Security
Method
The 8.0.0 review is published in full as security-review-8.0.0.md. It asked two questions. What can each new feature be made to do that it should not? And where does the code follow a rule in most places and miss it in one or two?
My rule for it was that anything rated Medium or higher gets fixed, even when the fix is big. Claude Code did most of the finding and fixing. Every finding was reproduced and fixed on a seeded copy of the product, never on anyone's installation, and each fix has tests that were also run against the code with the fix taken out.
The second question found most of the problems, so it was answered with lists generated by script, and the ratio was printed each time. The command queue, for example, has 30 writers: 12 ask for approval or call a gateway that does, 18 are listed with a reason, and none is neither. A 4-of-8 ratio found a bug in host deletion, which cleared four of the eight settings kept by host id and left the other four behind.
Scanners ran on the final tree: CodeQL, bandit, semgrep, gitleaks, shellcheck, pip-audit, nuclei and wapiti. Where a scanner could be given something it ought to find, it was. gitleaks got three planted tokens and found all three, and semgrep got a known-bad file and flagged it.
The authorization matrix called every routed operation (1,106 of them, taken from the real route tables) as 26 kinds of caller, from the platform operator and scoped roles to roles of two organisations, API keys, host tokens, a wrong token and no token. Each caller went against the objects of its own organisation, of the other one and of the default one, and every answer was judged against the check the handler itself names. That came to 86,805 requests in 60 runs, on the final tree. The review found no way for a route added in 8.0.0 to reach another organisation's data.
Generated tests (29 Hypothesis properties) found five of the 19, one of them a Medium. A run of 1,904 hostile requests to the routes added since 7.5.0, with every optional module off and then on, produced no 500, no exception and no unanswered request. The release also went through the full suite of about 22,000 tests on the JSON and SQLite storage backends before it was tagged.
Findings
One High, nine Medium, eight Low or hardening items and one informational item, 19 in all, and every one is fixed. The review lists each with the test that covers its fix.
The High was in the web page. The settings form in a host's drawer read nine fields from a list that never carried them. If you changed only a host's group, the page posted those nine fields empty, and the server treats an empty list as "clear this". The host lost its command allowlist, its watched units and files and its log rules, and an agentless host lost its SSH mode, user and port. The form now asks the server for the host's own settings first, and stays read-only, with a line that says why, if the answer doesn't come.
Three of the Mediums were leaks between organisations on an installation with tenants. Two matched a host to your organisation by display name, so another organisation's host with the same name put its events into your compliance evidence and its held image updates on your page. The third was the Home page, which builds its summaries from stores that are not keyed by host: a tenant's users got figures for the whole installation, including open alerts by severity, monitors, VPN totals, backup jobs and the list of integrations with the addresses in their error texts.
One finding came out of a scanner being wrong. wapiti reported an SQL injection in the error_description parameter of the SSO callback. It was not one. The answer was the same redirect for every value, and the scanner had read the server's rate limit, a 429, as a difference between its true and false probes. But the report pointed at that handler, and reading the handler showed that the callback wrote error and error_description to the error log as they came. A line break in either started a log line of its own, so anyone who could reach the server could add a [remotepower] ... entry. Both values now go through the log helpers, which turn control characters and line separators into ? and cut the code to 80 characters and the description to 240.
Python's isdigit() accepts characters that int() refuses:
"Β²".isdigit() # True
int("Β²") # ValueError: invalid literal for int() with base 10: 'Β²'
The code checked text with isdigit() and then called int(), so a superscript two in a port, a CIDR, a cron field or an object id turned a 400 into a 500 in 17 places. The worst case was a container report that listed Β² as a published port, which made three fleet views answer 500 for every user.
One defect turned up by accident. A system update moved the development machine to OpenSSL 4.1.0 in the middle of the pre-release test run, and the test that runs a real agent against a real HTTPS server began failing every time. The cause was a defect in the product. Server certificates issued by the built-in CA (tools/gen-ca.sh and the Settings button that generates a CA and a server certificate) had no authority key identifier, which RFC 5280 asks for in every certificate a CA signs. OpenSSL 4.1 and Python 3.13 or later refuse such a certificate with Missing Authority Key Identifier, so an agent pinned to a generated CA could not connect from a host that has both. Both generators add the extension now, and gen-ca.sh checks its own output in strict mode. The tests meant to cover this had run openssl verify without strict mode, which accepts the old certificate.
Three more Mediums:
- A host name that started with
=ran as a formula when a CSV export was opened in a spreadsheet. - The declarative export, which is meant to be committed to a repository, held webhook header values (an
AuthorizationorX-API-Keycredential, say) in plain text. An earlier fix had masked them in the support bundle and the backup and missed this third place. - Run command on an SSH host, the Ansible runner and the web terminal ignored quarantine and maintenance mode, which the command queue and the SSH gateway already honoured. All three ask the same question as the queue now, and a test finds the command channels in the syntax tree and checks that each one asks it.
Guardrails on the new features
The MCP endpoint, Traffic, Detections and automatic image updates are all off until you switch them on.
- The MCP endpoint can only read. A tool call is a request for one of the server's own read routes, made with the caller's own token, and it passes through every check the web server's front door makes. A test asserts that this list of checks equals the list in the request handler, so a check added there and missing here fails the build.
- The handshake monitors connect to the address they are given, so each passes an address rule when it connects. Link-local and cloud-metadata addresses are always refused and loopback only where allowed, and the address is checked when the name is resolved and again when the connection is made. The agent and the satellite carry a copy of the server's probe code that a script writes and a test checks is identical.
- Traffic captures no packets and reads no payload. The agent reads its connection table with
ss, adds up what each connection moved by remote address, port and program, and sends the 100 busiest rows. - Detections runs over data the server already holds. It opens no connection and runs no command on a host, and one sweep raises at most 100 alerts for the whole fleet, worst first, so a single address that turns bad cannot flood an inbox.
- Automatic image updates put commands on a host through the same gateway as every other command, so maintenance mode, quarantine, audit mode and four-eyes approval apply. Turning the mode on needs a fresh sign-in.
Not covered
- A live probe of a running installation: every probe ran against a seeded copy.
- Real Windows and macOS hosts. Traffic, the app finder and the rollback are Linux-only.
- Real services behind the connectors. The UniFi, Tailscale, Headscale and Cloudflare connectors ran against stand-ins written from the vendors' published descriptions, and no Apprise server was run.
- Safari itself. WebKit 26.4 as built by Playwright ran on Linux, next to Firefox and Chromium.
Two limits are by design. The agent runs as root, so a fully compromised server is root on its hosts. And a role scoped to groups, tags or sites limits what a user can change but does not hide the other hosts, so give anyone who must not see them a tenant. If you find something the review missed, please report it privately through GitHub's Report a vulnerability form.
Upgrading
- Update the agents. The agent version is 8.0.0, and finding apps, the new monitor types and the image-update rollback all run on the host.
- Hard-reload the dashboard once so the new front end loads.
- Long pages open as tabs now. One long page under My Account β Appearance β Page sections gets the old layout back.
- A host in quarantine or maintenance mode refuses Run command, an Ansible run and the web terminal. All three ignored it before.
- Deleting a host takes more with it: its CMDB record (notes, documents and credentials), runbook, schedules, mutes, backup jobs and scan schedules, and its place in groups, services and links. Tickets, time entries, alerts, the audit trail and command history stay.
- Server certificates from the built-in CA name their issuer now. An older certificate keeps working where it did; to replace it, run
tools/gen-ca.shagain or press Generate certificate in Settings. The CA is reused, so agents keep their trust. - Settings β Alerts inbox has a new switch, "Let every signed-in user acknowledge, resolve and assign alerts". It is on, as it was; turn it off to limit those actions to administrators.
Getting it
The release page has the tarball, a detached signature and a SHA-256 file, and the tag is signed. The container images (remotepower and remotepower-agent) are on GitHub's container registry for amd64 and arm64, and the install guide shows how to verify their cosign signature before you run them:
docker pull ghcr.io/tyxak/remotepower:8.0.0
cosign verify ghcr.io/tyxak/remotepower:8.0.0 \
--certificate-identity-regexp '^https://github.com/tyxak/remotepower/\.github/workflows/release\.yml@' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
The release page and the wizards guide are in the repo, the install guide covers the rest, and a read-only demo runs 8.0.0.
The text this release added is available in Chinese, Hindi, Spanish, Arabic, German and French, and no native speaker has read it yet. If a line reads wrong in your language, open an issue or start a discussion and tell me.
I drafted this post with Claude Code. Its figures come from the 8.0.0 release notes and the security review in the repo.
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes β full credit and traffic to the original publisher.