Fusebox is closed source and it asks for SSH credentials. That's a reasonable thing to be suspicious about, so here is the complete list of what it executes, generated from the source.
How it connects. Plain SSH, with a password or an RSA key in OpenSSH format. Ed25519 and ECDSA keys are not supported yet — the SSH library underneath only parses RSA. Nothing is installed on the server, no agent, no daemon, no cron job. There is no Fusebox server: your phone talks to your server and to nobody else. Credentials live in the iOS Keychain, and the host key is verified before any credential is sent.
Commands marked SUDO only run when you tap the action that needs them. A few marked SUDO -n try passwordless sudo and give up quietly instead of prompting you for anything: one in the Health Score, one in Network tools' neighbours scan, one in a sudo diagnostics tool tucked into the Systemd screen. Everything else — every metric, every service check — is read-only and unelevated.
hostname | Name shown in the header |
uname -r | Kernel version |
cat /proc/device-tree/model | Device-tree model string. On a Raspberry Pi (or another SBC that exposes one) this names the exact hardware; most VPS and NAS kernels don't have this file at all, and the read just comes back empty |
. /etc/os-release && echo "$PRETTY_NAME" | Distribution |
hostname -I | Local addresses |
tailscale ip -4 | Only to offer you the address for remote access. Fails silently if Tailscale isn't installed |
A separate one-shot batch that fingerprints the host, so the commands below know what to expect instead of assuming a Raspberry Pi:
uname -s · uname -m | Kernel name and CPU architecture |
( . /etc/os-release && echo "$ID" ) | Distribution ID, used to pick sensible defaults for the checks below |
command -v apt|dnf|pacman|apk|zypper | Which package manager is installed, tried in that order — feeds the update-staleness check in the Health Score |
Every readable /sys/class/thermal/thermal_zone*/type, hwmon*/name and hwmon*/temp*_input | Every temperature source the host exposes, so Fusebox can pick whichever one is actually the CPU sensor instead of assuming a fixed path |
awk over /proc/self/mountinfo, then cat /proc/diskstats | Resolves which diskstats row is the root filesystem's device, from the mount table rather than a guessed list of device names |
cat /proc/device-tree/model | Same read as above, this time just to decide whether the host is a Raspberry Pi — gates the vcgencmd extras further down |
grep -c ^processor /proc/cpuinfo | Core count |
Readability check on /proc/stat, /proc/meminfo, /proc/uptime, /proc/net/dev | Confirms the universal /proc files the CPU, memory and network cards depend on are actually there, so a missing one shows as absent instead of a fabricated zero |
cat /proc/stat | CPU, total and per core |
cat /proc/meminfo | Memory and swap |
cat /proc/uptime | Uptime |
df -P -k / | Disk usage |
cat /proc/net/dev | Network throughput |
cat /proc/loadavg | Load average |
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq | Clock speed |
| Read of whichever thermal path was found above | Temperature — a thermal-zone or hwmon path picked by the platform check, not a hardcoded one. Absent entirely on a host with no readable sensor |
awk '$3=="<device>"' /proc/diskstats | Disk I/O, for the root device the platform check resolved |
ps -eo pid,user,%cpu,%mem,comm --sort=-%cpu --no-headers | head -5 | Top 5 processes by CPU, for the dashboard's quick preview card |
vcgencmd get_throttled · vcgencmd measure_temp | GPU temperature and throttling / undervoltage flags — only when the platform check found a Raspberry Pi |
When a background check runs with the app closed, this whole batch runs once, and /proc/stat is read twice, a second apart, so a CPU rate can be computed without a previous sample to compare against.
systemctl list-unit-files --type=service --no-legend --plain | What's installed, and whether it's enabled at boot. Skipped on a host with no systemd |
systemctl list-units --all --type=service --no-legend --plain | What's loaded and what state it's in |
docker ps -a --format '{{.Names}}|{{.Image}}|{{.Status}}|{{.Ports}}' | Containers, images, status and published ports. Skipped when Docker isn't installed |
ids=$(timeout 5 docker ps -aq) | Collects the container IDs the next command inspects |
docker inspect --format '{{.Name}}|{{.HostConfig.RestartPolicy.Name}}|{{.State.OOMKilled}}|{{.State.ExitCode}}|{{.State.FinishedAt}}' $ids | Restart policy and exit code, to tell a deliberate stop from a crash |
ps -eo comm= · ss -ltn · ss -lun · cat /proc/uptime | Corroborating signals and the reboot guard for alerts. Never used alone to identify a service |
Every probe is curl -s -o /dev/null -w '%{http_code}' --connect-timeout 1 --max-time 2 against the address the container actually publishes, chosen from its port mapping rather than assumed:
Home Assistant → :8123/ | HTTP status only |
Plex → :32400/identity | Unauthenticated by design |
Jellyfin → :8096/System/Info/Public | Public endpoint |
Node-RED → :1880/settings | Answers 200 or 401; either proves it's alive |
OctoPrint → :5000/api/version | No API key needed for version |
Frigate → :5000/api/version | Internal port, unauthenticated |
Syncthing → :8384/rest/noauth/health | Explicitly the no-auth endpoint |
Grafana → :3000/api/health | Unauthenticated by design |
Transmission → :9091/transmission/rpc | The 409 handshake is proof of life |
Pi-hole, AdGuard Home, Mosquitto, Zigbee2MQTT, Portainer and Uptime Kuma have no endpoint that answers without credentials, so Fusebox does not probe them and says running, unverified instead of pretending to know.
docker ps -a -s --format '{{.Names}}\t{{.Status}}\t{{.Image}}\t{{.Size}}\t{{.Ports}}' | The Docker screen's own list, including image size |
docker start|stop|restart NAME | Container buttons |
docker logs --tail 50 NAME | The Logs button |
docker inspect NAME | The Inspect sheet, full raw output |
docker pull IMAGE | Pulls a newer image. It does not recreate the running container — that one keeps its old image until you recreate it yourself |
docker rm -f NAME | Remove, behind a confirmation |
systemctl list-units --type=service --all --no-legend --no-pager --plain | Refreshes the full unit list when you open the Systemd screen or pull to refresh — separate from the batch that drives the service cards |
systemctl start|stop|restart UNITSUDO | systemd controls |
journalctl -u UNIT --no-pager -n N | Unit logs |
whoami · sudo -n true · executeSudo whoamiSUDO -n | A sudo diagnostics tool tucked into the Systemd screen — shows exactly what each auth path returns |
top -bn2 -d 0.5 -o %CPU|%MEM -w 256 | awk ... | head -25, falling back to ps -eo pid,user,%cpu,%mem,comm --sort=-%cpu|-%mem --no-headers | head -25 | Process list. Two top samples give real-time %CPU; the ps fallback only kicks in when top isn't available (BusyBox, minimal images), and its %CPU is cumulative rather than live |
kill -SIGNAL PIDSUDO | Killing a process, behind a confirmation. Elevated because the list includes processes you don't own |
ip -o addr · ip -o link · ip route get 8.8.8.8 · ss -tunlH | The network screen |
ping -c 4 -W 2 HOST | Network tools · ping |
traceroute -n -w 2 -m 15 HOST | Network tools · traceroute |
dig +short A|AAAA|MX HOST, falling back to host HOST then getent hosts HOST | Network tools · DNS, whichever of the three exists |
arp-scan --localnetSUDO -n, falling back to ip neigh show then arp -a | Network tools · neighbours. The sudo attempt is sudo -n and failure is expected |
For p in 22 80 443 53 25 110 143 3306 5432 6379 8080 8443 9000 27017: timeout 1 bash -c "echo > /dev/tcp/HOST/$p" | Network tools · common-port check against a host you type |
| Whatever you typed | The terminal and your own saved commands run exactly what you wrote, nothing added |
grep -E '^cpu ' /proc/stat · free -m · cat /sys/class/thermal/thermal_zone0/temp · df -P / · cat /proc/loadavg · nproc | A fresh, independent metrics sample for the assessment — its own round trips, not the dashboard's cached numbers. The temperature read here is a fixed thermal_zone0 path rather than the sensor the platform check found, so a host with a temperature reading only on hwmon shows nothing in this one sample |
vcgencmd get_throttled | Under-voltage and throttling flags for the Health Score. Raspberry Pi only, and a second, independent read of the same command the Metrics batch already made |
findmnt -no SOURCE / | Whether root is on an SD card. The resulting advice only surfaces on a Raspberry Pi; other hosts booting off eMMC or similar just fall through with no finding |
getent passwd pi | Whether the default account still exists. Raspberry Pi only — "pi" means nothing on any other distro |
sudo -n grep PasswordAuthentication /etc/ssh/sshd_configSUDO -n | Whether SSH still accepts passwords. On stock Raspberry Pi OS that file is world-readable and sudo is unnecessary; the elevation is there for systems that lock it down, and it gives up quietly |
ip route get 8.8.8.8 | Whether the primary route goes out over WiFi — less reliable than Ethernet for a server left running 24/7 |
stat -c %Y <package-cache-path> | How long since the last package index refresh. The path depends on whichever package manager the platform check found: apt's cache file, dnf's or zypper's cache directory, pacman's sync directory, apk's cache |
cat /proc/uptime | Flags an uptime over 90 days as a reboot you're probably overdue for, after kernel updates |
If you saved a sudo password, it is piped to sudo -S for that one command and never written anywhere on the server. If you didn't, Fusebox tries sudo -n, which only works when your user already has passwordless sudo, and gives up cleanly when it doesn't. It never edits sudoers, never installs a helper, and never keeps a session open.