cve-scan is a local audit program for Arch Linux. It runs on your laptop as a regular user. It checks for out-of-date packages, known CVEs, AUR supply-chain indicators, and basic system integrity, then reports through your notification daemon.
In June 2026, the Atomic Arch attack on the Arch User Repository compromised 1,500+ packages with an infostealer and an eBPF rootkit. Signature tools could not detect that class of malware. cve-scan watches for the known signs and tells you when something matches.
- Arch Linux with systemd (user services)
- pacman 7.1 or newer
- jq, sqlite3, flock, arch-audit, checkupdates, vercmp
- udisks2 for the device health checks
- a notification daemon: mako, swaync, or hyprctl (auto-detected)
scripts/check-requirements.shverifies the host
The repo is public and tag-pinned. The laptop pulls the tag read-only.
- Clone the repo:
git clone https://github.com/Keylessboi/cve-scan.git - Checkout the release tag:
git checkout v0.1.0 - Run the installer:
./bin/install.sh - The installer enables the timers:
systemctl --user list-timers cve-scan-daily.timer cve-scan-weekly.timer
The installer copies the program to ~/.local/share/cve-scan/, the units to
~/.config/systemd/user/, and the config to $XDG_CONFIG_HOME/cve-scan/config.
It never runs with sudo and never touches system units.
An optional root helper (bin/install-root.sh, run with sudo) adds live
firewall summaries. It is a separate, opt-in system half: the scanner keeps
working without it and reports firewall data as unavailable. The scanner
itself still never runs as root.
The scan state shows in your bar as one pixel-art block. It uses hard pixel frames: a 2px border, a drop shadow, square corners, and no gradients. The glyph changes with the scan outcome.
"custom/cve-scan": {
"exec": "~/.config/cve-scan/waybar/cve-state.sh",
"interval": 15,
"format": "{}",
"tooltip-format": "{tooltip}",
"on-click": "notify-ctl action-open-report"
}
Copy the style rules from waybar/cve-scan.css into your waybar style.css.
The module needs a pixel-style monospace font (DepartureMono Nerd Font or
Maple Mono NF fall back automatically). States:
| State | Glyph | Color |
|---|---|---|
| clean | ✅ | green |
| warnings or updates | 🟡 | amber |
| danger | 🔴 | red, pulses |
| deferred | ⏳ | orange |
| error | 🛑 | red, blinks |
Copy etc/cve-scan.conf.example to $XDG_CONFIG_HOME/cve-scan/config and edit it.
| Key | Meaning |
|---|---|
quiet_hours_begin |
Start of the quiet window (24h clock). Default 23:00. |
quiet_hours_end |
End of the quiet window. Default 07:00. |
notify_backend |
auto, mako, swaync, or hyprctl. Default auto. |
battery_capacity_threshold |
Weekly scan defers at or below this percentage while discharging. Default 60. |
ioc_enabled |
Set to 1 to run AUR-IOC checks. Default 1. |
off_device |
Set to 1 when this machine is not the primary device. The daily scan defers the package-state and device checks and exits with code 3. |
device_disk_warn_pct |
Warn when disk usage reaches this percentage of the root filesystem. Default 90. |
device_mem_warn_pct |
Warn when available memory falls to this percentage of total memory. Default 15. |
smart_wear_threshold |
Escalation gate for SMART critical warnings. Default 80. |
battery_warn_pct |
Warn when battery health is at or below this percentage. Unset by default. When unset, battery health is information only. |
pkgstate_window_days |
How far back to look for package downgrades and regressions. Default 7. |
pkgstate_log_format |
Pacman log format: auto, iso, legacy, or never. Default auto. |
pkgstate_allowlist |
Comma-separated package names that are exempt from downgrade warnings. Empty by default. |
Quiet hours suppress progress and summary notifications; a danger finding always fires.
The daily scan runs four modules in this order: cve, pkgstate, hygiene, device. The weekly scan runs two modules: integrity, aur. The weekly scan is battery-aware; the daily scan is not.
| Code | Meaning |
|---|---|
| 0 | Clean. No findings. |
| 1 | Danger. At least one danger finding. |
| 2 | Error. The scan could not complete. |
| 3 | Deferred. The weekly scan skipped (battery). |
| 4 | Warnings only. |
A danger finding is a confirmed match against the vendored IOC list. It is persistent and red, never auto-replaced by a progress or summary notification, and carries an "Open report" action. Only you can resolve it. A warning is an amber suspicion or a stale signal that the next clean scan can resolve.
The report is a plain-text file in the state directory. Each finding lists the
tool, module, package or file, and severity. The daily summary notification
shows finding counts; the danger notification carries an "Open report" action
that opens the newest report. The report path is
$XDG_STATE_HOME/cve-scan/reports/audit-YYYYMMDD.json.
systemctl --user disable --now cve-scan-daily.timer cve-scan-weekly.timerRemove ~/.local/share/cve-scan/, $XDG_CONFIG_HOME/cve-scan/, and $XDG_STATE_HOME/cve-scan/.
Last reviewed: 2026-08-09
