Threat Intelligence
A default aur-scan is fully offline and static — it reads the PKGBUILD and
nothing leaves your machine. Threat intelligence is an opt-in layer on top:
when you turn it on and supply your own API key, the scanner cross-checks the
artifacts a package declares against two reputation services. It is off until
you enable it, and it is designed so that turning it on can’t quietly turn into
a privacy or security problem.
What it checks
Two providers, each fed only data that is already public in the PKGBUILD:
| Provider | Looks up | Emits |
|---|---|---|
| VirusTotal | each declared sha256sums hash (file by hash) | TI-VT-001 when engines flag it |
| abuse.ch / URLhaus | each source= http(s) URL | TI-URLHAUS-001 when the URL is a known malware-distribution URL |
The point is the gap that static analysis can’t close on its own: a -bin
package’s prebuilt artifact, or a source URL, may be known bad to the wider
security community even when the PKGBUILD text looks clean. A hash or URL lookup
answers “has anyone already seen this and flagged it?” without ever downloading
or running the artifact.
Off by default — and why that matters
A security tool that phones home by default is its own problem. So:
- The networked analyzer is never even constructed unless you set
enable_threat_inteland a provider key is present. No key, no analyzer, no calls. - A scan with no configuration makes zero outbound requests. The offline, static behavior described in How it works is unchanged.
What leaves your machine (and what never does)
Least disclosure. Only data already public in the PKGBUILD is ever
transmitted — a declared content hash, or a source= URL. Never file
contents, never anything about you or your system. URLs have their fragment
stripped; hashes are validated as clean hex before they’re ever placed in a
request path.
All third-party network code lives in one auditable file
(threat_intel/remote.rs) so the project’s entire external egress can be
reviewed in one place. Every call is:
- HTTPS-only, with redirects refused (a followed redirect is the classic exfil amplifier),
- time-bounded (a short timeout — intel is advisory, never a blocker),
- fail-open: a network error, bad key, quota limit, or outage yields no finding and never fails the scan. A provider being down must never block an install.
- bounded per scan: a hard cap on lookups stops a hostile PKGBUILD declaring hundreds of sources to burn your API quota.
Verdict cache
Lookups are cached in a per-user, MAC-authenticated on-disk cache (owner-only directory, keyed integrity) so repeat scans respect VirusTotal’s public quota (4 requests/minute). The cache draws a deliberate line between a definitive answer (e.g. VirusTotal has genuinely never seen a hash — cached) and a transient failure (network blip, quota, outage — not cached, so a one-off outage can never suppress a real verdict for the cache lifetime). Verdict lifetime is configurable.
Turning it on
Threat intel reads from a config file you point to with -c. Keep it
chmod 600 — it holds your keys — and never commit it.
# ~/.config/aur-scanner/ti.toml (chmod 600)
enable_threat_intel = true
min_severity = "low"
[threat_intel]
# VirusTotal: https://www.virustotal.com/gui/my-apikey
virustotal_api_key = "PASTE_YOUR_VT_KEY"
# URLhaus / abuse.ch: an Auth-Key is now mandatory — free at https://auth.abuse.ch/
urlhaus_enabled = true
urlhaus_auth_key = "PASTE_YOUR_URLHAUS_KEY"
cache_duration_hours = 24# point any scanning command at the config
aur-scan -c ~/.config/aur-scanner/ti.toml scan ./mypkg
aur-scan -c ~/.config/aur-scanner/ti.toml check <package>
aur-scan -c ~/.config/aur-scanner/ti.toml system # VT-check every installed AUR packageKeys can also come from the environment instead of the file:
VT_API_KEY / VIRUSTOTAL_API_KEY and URLHAUS_AUTH_KEY.
The offline cousin: the IOC database
Separate from the network lookups, every build ships a local, offline indicator-of-compromise database — known-malicious package names, npm/bun payload names, and file artifacts from tracked campaigns (including the June 2026 Atomic Arch incident). It needs no key and no network:
aur-scan ioc # campaigns + indicator stats
aur-scan ioc --check <name> # is this a known-malicious indicator?aur-scan system cross-references everything you have installed against it
automatically — the fastest answer to “am I affected?”
Honest limits
This is advisory, defense-in-depth — not a verdict you can rely on alone. A
clean reputation result means “nobody has flagged this yet,” not “this is safe,”
and every lookup fails open. It strengthens the static scan; it doesn’t replace
the judgment of reading what a package does. As always, aur-scan never follows
or runs the things it’s suspicious of.