Omahub
← All plugins
G

Proxmox

by Guillaume Desoutter

Proxmox VE guest status, CPU and memory usage in the Omarchy bar.

Security review

Review recommended · 3 findings

Deterministic scan — not a security guarantee

Low
Risk level
Low
Analyzed commit
916e37b
Scanned
1 month ago

Flagged patterns appear only in documentation files (README / docs) — descriptive examples, not executable code.

  • Docs external_hosts README.md:63

    Downloads or connects to an external HTTP(S) host.

    curl -s -o /dev/null -w '%{http_code}\n' https://your-node.example.com:8006/api2/json/version
  • Docs sudo README.md:56

    Command runs with sudo, elevating the process beyond the plugin environment.

    sudo cp pve-root-ca.pem /etc/ca-certificates/trust-source/anchors/pve.crt
  • Docs sudo README.md:57

    Command runs with sudo, elevating the process beyond the plugin environment.

    sudo trust extract-compat

Automated analysis only — not a security guarantee.

AI advisory review

No obvious issues detected

Language-model assessment · ~deepseek/deepseek-v4-flash-latest — advisory only

None
AI risk level
None
Recommendation
install
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
916e37b
Reviewed
1 month ago

The plugin is a read-only Proxmox VE status poller: it runs a constrained shell script that validates the endpoint, sources a user-provided credentials file, and issues GET requests via curl without disabling TLS verification. The deterministic scan's medium findings are all in README setup instructions (sudo and example curl commands) and are not executed by the plugin itself. No obfuscation, persistence, destructive behavior, or credential exfiltration was found.

How this check works

This review combines the deterministic scan (the rule-based results above) with an independent look at the plugin's code by a language model. The model reads a trimmed sample of the repository's files, the manifest, and the README, then gives a plain-language risk level and a recommendation: install (no notable danger), review (look closer first), or avoid (clearly dangerous).

It runs on the same analyzed commit as the deterministic scan and is strictly advisory — it is not a security guarantee and never blocks a plugin by itself. A human moderator still reviews plugins before they are listed.

AI advisory only — automated analysis, not a security guarantee.

Install
$ omarchy plugin add https://github.com/g-desoutter/omarchy-plugin-proxmox --enable
System #bar #system

Proxmox Plugin for Omarchy

A bar widget for Omarchy Quattro showing Proxmox VE guest status, CPU and memory usage at a glance.

The bar shows running / total. Click it for a panel listing every guest with its live metrics. The widget turns to the bar's alert colour when the API is unreachable, or when a guest you explicitly watch is not running.

The Proxmox widget and its panel in the Omarchy bar

Requirements

  • curl and jq on the machine running Omarchy
  • A Proxmox VE API token with the read-only PVEAuditor role

Setup

1. Create a read-only API token

On your Proxmox node:

pveum user add omarchy@pve --comment "Omarchy bar widget (read-only)"
pveum user token add omarchy@pve bar --privsep 1
pveum acl modify / --users  'omarchy@pve'     --roles PVEAuditor
pveum acl modify / --tokens 'omarchy@pve!bar' --roles PVEAuditor

The token secret is displayed once, at creation. Copy it now.

Both ACL lines are required. With privilege separation enabled the token's effective permissions are the intersection of the user's and the token's, so granting the role to only one of them yields no access at all — and /cluster/resources returns an empty list rather than a 403.

2. Store the credentials outside shell.json

install -d -m 700 ~/.config/omarchy/proxmox
cat > ~/.config/omarchy/proxmox/credentials <<'EOF'
PVE_TOKEN_ID='omarchy@pve!bar'
PVE_TOKEN_SECRET='<the secret from step 1>'
EOF
chmod 600 ~/.config/omarchy/proxmox/credentials

Single quotes matter: the token id contains !, which bash would otherwise treat as history expansion.

Never put the token in shell.json. That file is plugin configuration, not a secret store, and it is the kind of file people keep in their dotfiles repo. The widget only ever learns the path to the credentials file.

3. Trust the cluster CA

Proxmox generates its own PKI at install time. Copy the cluster CA to the system trust store so TLS verification succeeds without special-casing:

# Print it on the node, paste it locally
cat /etc/pve/pve-root-ca.pem

sudo cp pve-root-ca.pem /etc/ca-certificates/trust-source/anchors/pve.crt
sudo trust extract-compat

Verify — a 401 means the TLS handshake succeeded and only authentication is missing, which is what you want at this point:

curl -s -o /dev/null -w '%{http_code}\n' https://your-node.example.com:8006/api2/json/version

The endpoint host must match the certificate's CN or a SAN entry. Check what the node presents with:

openssl s_client -connect <node>:8006 </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -ext subjectAltName

If you prefer not to touch the system trust store, point the caBundle setting at a local copy of the CA instead.

Install

omarchy plugin add https://github.com/g-desoutter/omarchy-plugin-proxmox.git --enable

Settings

Settings are inline on the widget's entry in ~/.config/omarchy/shell.json:

{
  "id": "io.github.gdesoutter.proxmox",
  "endpoint": "https://your-node.example.com:8006",
  "label": "homelab",
  "watchedGuests": [500]
}
Key Default Description
endpoint https://proxmox.example.com:8006 PVE API base URL. Must match the certificate CN or a SAN.
credentialsFile ~/.config/omarchy/proxmox/credentials Absolute path to the credentials file.
caBundle (system trust store) Absolute path to a CA bundle, if you did not install the CA system-wide.
interval 15 Refresh interval in seconds. Values below 10 gain nothing — see below.
label (the endpoint) Name shown in the panel header.
watchedGuests [] VMIDs whose shutdown is abnormal. Empty means never alert on a stopped guest.

allowMultiple is enabled, so you can add one widget per cluster.

On watchedGuests

A stopped guest is not inherently a problem — lab VMs and templates are meant to be off. The widget cannot know your intent, so you declare it: list only the VMIDs whose absence is genuinely abnormal. Everything else is ignored, and the widget stays quiet.

Notes

Refresh interval. pvestatd refreshes /cluster/resources roughly every 10 seconds, so polling faster than that re-reads the same sample. The widget floors the interval at 10s for this reason. Guest status changes, unlike metrics, are immediate — stopping a VM is reflected on the next poll, or instantly via the panel's refresh button.

Memory figures. mem is memory as seen by the hypervisor, not pressure inside the guest. A Linux guest filling its page cache, or a Windows guest caching aggressively, will read high without being short of RAM. Don't size guests from this number; check Available Memory inside the guest instead.

CPU figures. cpu is already normalised across all vCPUs assigned to the guest, so 100% means the guest is saturating its allocation — not one core.

Guest OS icons. The OS type comes from each VM's ostype config field, which is declarative rather than detected — a guest created with the wrong value shows the wrong icon. It is cached for 24 hours under $XDG_CACHE_HOME/omarchy-proxmox, so the extra request happens once per guest per day.Containers always show the container icon.

Privileges

The plugin issues a single read-only GET /api2/json/cluster/resources?type=vm through curl. It never writes to the cluster, never runs an install hook, never asks for sudo, and never disables TLS verification. The poller is a plain shell script in bin/ — read it before enabling the plugin.

Like every Omarchy plugin, this runs unsandboxed inside the long-lived shell process, with your user's permissions.

Remove

omarchy plugin remove io.github.gdesoutter.proxmox

License

MIT — see LICENSE.