pvewarden@0.1.7
CAUTION· not startedPublisher claims: "Enables AI agents to inspect pending updates and service health for Proxmox VE VMs and containers, then take snapshots, apply official updates, reboot, and roll back under tag-based permissions and human-confirmed risky actions." Observed in sandbox: no network, touches nothing outside the project, writes no memory.
Coverage
Not started: dependency install failed; the server itself was not observed.- Tested
- the dependency install step · every file read, file written and host contacted by what ran
- Not tested
- server startup · the tool list · tool behavior
What this means for the label: Caution here covers what ran. The server's tools were not exercised with a real credential, so nothing about their behavior is asserted; the credential summary below says what to do with that.
Before you give it your token
- It will ask for
TOKEN_SECRET_ENVConfiguration, not credentials: PUBKEY, PVEWARDEN_CONFIG- Where it talks to
- no vendor host named in the code
- What the honeypot saw
- no credential files read · no network
- What we could not test
- server startup · the tool list · tool behavior
Connect it with a scoped credential, under the guard. It asks for TOKEN_SECRET_ENV and talks to its vendor. Give the credential to the guard, not the server: the value never enters the server's environment and only travels to the host you bind. What the tools do with a real credential was not observed.
Never paste a credential into a chat, a ticket or a report, including ours. How the guard holds it.
Is [email protected] safe to install?
KillerSkills ran it in the KillerSkills honeypot sandbox (2 scenarios; not started: dependency install failed; the server itself was not observed) on 2026-11-11 and scored it 71/100 (Caution). It is not known to be malicious, but it has behaviour or code a security policy should decide on before install. Notable findings: Access to sensitive file paths; Destructive file system command detected; Auto-update or dynamic fetch configuration. Summary: no network, touches nothing outside the project, writes no memory.
Behavior trace
Honeypot run · 0 s · 2 scenarios · 0 deviationsStatic findings
SUDOERS=/etc/sudoers.d/pvewardenFix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.rm -rf /var/lib/pvewardenFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.@pytest.mark.parametrize("command", ["id", "check; id", "bash -i", "cat /etc/shadow", "sudo -l"])Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.# install.sh [--dry-run] [--auto-updates=keep|off|on] "<server public key>" <server address>Fix: Pin versions and sources; vendor anything fetched at install time.return subprocess.run(args, capture_output=True, text=True, check=check, **kwargs)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out."chmod +x /usr/local/bin/systemctl") # fmt: skipFix: Request the narrowest permission that works; replace wildcards with the exact paths or hosts.chown root:"$SVC_USER" "$ETC/config.toml"Fix: Request the narrowest permission that works; replace wildcards with the exact paths or hosts.subprocess.run([*ossl, "-new", "-subj", "/CN=pvewarden", "-keyout", d / "tls.key", "-out", d / "tls.csr"],Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.assert subprocess.run(["openssl", "verify", "-CAfile", pve_ca, cert], capture_output=True).returncode == 0Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out."id pvewarden; ls -d /usr/local/sbin/pvewarden-* /etc/sudoers.d/pvewarden /etc/apt/apt.conf.d/52pvewarden* /var/lib/pvewarden",Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.# A minimal "guest": the distribution image plus sshd, without sudo (like the Debian LXC templates).Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.echo " WARNING: still on although --auto-updates=off: another apt.conf.d file overrides $AUTO_CONF"Fix: Pin versions and sources; vendor anything fetched at install time."auto_updates=true means the guest also installs updates by itself every day (unattended-upgrades) "Fix: Pin versions and sources; vendor anything fetched at install time.subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.def build_app(server: MCPServer, cfg: HTTPConfig, audit: AuditLog):Fix: Namespace tool names and keep tool descriptions literal; no instructions to the agent inside them.return subprocess.run(args, capture_output=True, text=True, check=check, **kwargs)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.subprocess.run(["ssh-keygen", "-q", "-t", "ed25519", "-N", "", "-C", name, "-f", d / name], check=True)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.--auto-updates=keep | --auto-updates=off | --auto-updates=on) AUTO=${a#*=} ;;Fix: Pin versions and sources; vendor anything fetched at install time.assert parse_status("auto_updates=yes\n")["auto_updates"] is TrueFix: Pin versions and sources; vendor anything fetched at install time.return subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.out.append(fail("Shared SSH key", f"{key} is readable or writable by everyone", f"chmod 0640 {key}"))Fix: Request the narrowest permission that works; replace wildcards with the exact paths or hosts.USAGE='usage: install.sh [--dry-run] [--auto-updates=keep|off|on] [--keep-keys|--keys-only] "<server public key>" <server address>Fix: Pin versions and sources; vendor anything fetched at install time.chown "$USER_NAME:$USER_NAME" "$tmp"Fix: Request the narrowest permission that works; replace wildcards with the exact paths or hosts.return subprocess.run(["bash", ROOT / "guest/pvewarden-gate"], env=env, capture_output=True, text=True)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.r = subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.chmod 0755 "$APP/venv/bin/pvewarden"Fix: Request the narrowest permission that works; replace wildcards with the exact paths or hosts.chmod 0640 "$ETC/config.toml"Fix: Request the narrowest permission that works; replace wildcards with the exact paths or hosts.assert "claude mcp add --scope user --transport http pvewarden https://192.0.2.50:8765/mcp" in r.stdoutFix: Replace encoded or assembled strings with plain literals and remove undeclared network calls.&& rm -rf /var/lib/apt/lists/* \Fix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.@pytest.mark.parametrize("command", ["id", "check; id", "bash -i", "cat /etc/shadow", "sudo -l"])Fix: Stop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.chmod 0600 "$tmp"Fix: Request the narrowest permission that works; replace wildcards with the exact paths or hosts.assert "curl.exe -sk https://192.0.2.50:8765/ca.pem" in r.stdoutFix: Replace encoded or assembled strings with plain literals and remove undeclared network calls.assert "claude mcp add --scope user --transport http pvewarden https://192.0.2.50:8765/mcp" in r.stdoutFix: Replace encoded or assembled strings with plain literals and remove undeclared network calls.assert r["auto_updates"] is TrueFix: Pin versions and sources; vendor anything fetched at install time.subprocess.run([*ossl, "-x509", "-days", "30", "-subj", "/CN=Proxmox Virtual Environment",Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.r = subprocess.run([proj / "proxmox/pvewarden-enroll", *args], env=env, capture_output=True, text=True)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.def test_enroll_passes_auto_updates_only_when_changing_it(enroll):Fix: Pin versions and sources; vendor anything fetched at install time.printf '// written by pvewarden (install.sh --auto-updates=%s); delete this file to undo\n' "$AUTO" > "$AUTO_CONF"Fix: Pin versions and sources; vendor anything fetched at install time.assert "MCP server https://192.0.2.50:8765/mcp" in r.stdoutFix: Replace encoded or assembled strings with plain literals and remove undeclared network calls.r = runner_running("exec yes pvewarden", max_output=2**20) # exec: kill hits it, like sshFix: Build commands from fixed arguments; do not interpolate untrusted strings into a shell.assert parse_status(out)["auto_updates"] in (True, False), outFix: Pin versions and sources; vendor anything fetched at install time.return subprocess.run(["bash", ROOT / "guest/install.sh", *args], capture_output=True, text=True)Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.subprocess.run(Fix: Build commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.assert "http://10.200.0.200:8765/mcp" in r.stdoutFix: Replace encoded or assembled strings with plain literals and remove undeclared network calls.assert "http://10.8.0.5:8765/mcp" in r.stdoutFix: Replace encoded or assembled strings with plain literals and remove undeclared network calls.assert "MCP server https://192.0.2.50:8765/mcp" in r.stdoutFix: Replace encoded or assembled strings with plain literals and remove undeclared network calls.assert "curl.exe -sk https://192.0.2.50:8765/ca.pem" in r.stdoutFix: Replace encoded or assembled strings with plain literals and remove undeclared network calls.Cost to the agent
Tokens estimated at four characters each. The tool list is re-read by the agent on every turn, so it is the number to compare between servers that do the same job: ranked across the index.
Known vulnerabilities
Vulnerability advisories (OSV) cover npm and PyPI packages; this registry has no advisory database.
What would make this Verified
9 points to 80 · weights: behavior 45%, static 25%, prompt 15%, publisher 15%- Unclaimed publisher≈ +8 on the totalClaim matousfiser: a verified publisher gets +50 on publisher trust. It is free and usually instant with GitHub sign-in.
- Access to sensitive file paths≈ +4 on the totalStop enumerating or reading credential locations; take secrets from a declared environment variable the user sets on purpose.
- Destructive file system command detected≈ +4 on the totalBuild commands from fixed arguments; do not interpolate untrusted strings into a shell.
- Auto-update or dynamic fetch configuration≈ +4 on the totalPin versions and sources; vendor anything fetched at install time.
- Privileged sudo command≈ +2 on the totalBuild commands from fixed arguments; do not interpolate untrusted strings into a shell.
- Python subprocess execution detected≈ +2 on the totalBuild commands from fixed arguments, never from interpolated strings; prefer an API client over shelling out.