Please do not open a public issue for security problems. Use GitHub's "Report a vulnerability" (private security advisory) on this repository. Include steps to reproduce and the affected version. You will get an answer within a week.
Only the latest release receives security fixes.
- Network access. The web dashboard listens on port 8443 (HTTPS) on all interfaces and is on by
default; turn it off with
PI_GUARD_DASHBOARD_ENABLED=false.install.shchooses a random first password; without it, as in Docker, it isadmin123unlessPI_GUARD_DASHBOARD_FIRST_PASSWORDis set. It must be changed at the first login, and nothing else works until it is. Telegram uses outbound long polling; signal-cli listens on localhost only; MQTT is an outbound client connection. - Updates. Agents and desktop apps check a signature, and a Pi installs only release tags signed with
a key that never leaves the owner's computer. A Pi trusts only the key in
/opt/pi-guard/release-signers, which updates cannot change. - Dashboard roles. The server enforces them with an allowlist. Viewers only watch and get no VPN access. Removing a person removes their devices, logins and VPN access. A new password ends that person's other logins. Passkeys, API tokens and key files need the password to be added.
- Authorisation happens centrally in the messenger for every provider: configured user IDs or single-use, expiring invitation codes; group chats must be allow-listed; per-user rate limiting; admin-only commands checked by role. Unknown senders are answered at most once per hour.
- No command execution. Chat commands map to fixed handlers. External programs (FFmpeg, ffprobe, ip) are started with argument lists, never through a shell. Uploaded audio is checked by file signature and parsed by ffprobe restricted to local files before it can be played.
- Least privilege. The service runs as a dedicated user with a hardened
systemd unit (
ProtectSystem=strict, no capabilities,NoNewPrivileges); the container runs read-only, unprivileged and without the Docker socket. - Secrets (bot token, MQTT and router passwords) are only read from the
environment file (
0640 root:pi-guard), are masked inconfig show, and are redacted from logs, including tracebacks. - Data at rest is readable only by the service user. Face embeddings are
kept in a separate database and deleted with
secure_delete. - MQTT commands are off by default and limited to setting the mode; restrict the topic with broker ACLs if you enable them.
- Telegram bot chats are not end-to-end encrypted.
- Anyone with physical access to the device or its SD card can read the recordings; pi-guard does not encrypt storage. Use full-disk encryption if this matters for you.
- signal-cli is an unofficial client maintained outside this project.