A collector reads what is installed on an application server. The agent sits on the reverse proxy and knows that machine. What runs behind it — a WordPress, a Laravel, the system packages of the box itself — the proxy can only guess at from traffic. A collector reads it from the disk and reports it.

A version taken from a request URL is a guess. For WordPress core it is often right; for a plugin it is usually the core's version, because that is what most themes put in ?ver=. So the software EdgeGuard infers from traffic is labelled an inference and deliberately never matched against a CVE database — guessing a version and then naming a CVE for it would turn one guess into a confident claim.
A version read from wp-includes/version.php, or from a composer.lock, is what is installed. It can be compared against a vendor's fix version and acted on. Every row a collector produces carries the file it was read from, so any finding traces back to a path on a named machine.
Three things, and they are the design rather than omissions. A collector runs on a machine the WAF operator may not own.
The blast radius of a bug in the collector, or of a compromised console, is bounded by there being no path from the console to that machine at all.
| Column | Meaning |
|---|---|
| NAME | the collector's name, with its hostname underneath |
| SITES SERVED | which sites this backend serves — declared, not guessed |
| STATE | awaiting first contact, reporting, silent, token expired, or revoked |
| SYSTEM | the distribution it reported, and its package manager |
| PACKAGES | how many system packages it read |
| APPLICATIONS | how many web applications it read, with a note when the scan was cut short or a path could not be read |
| LAST SEEN | when it last reported |
Three of those states are not faults and are not coloured as though they were. Awaiting first contact means a token was generated and nothing has enrolled with it yet. Silent means it enrolled, reported, and has not been heard from in a while. Token expired means an install was put off for more than an hour; generate a new token from the key button on its row.
Create the collector in the console first — a name, and the sites its backend serves. The console then prints a single command with the enrolment token already in it.

curl -fsSL https://artica-ad-agent.b-cdn.net/install-collector.sh \
| CENTRAL_URL='https://your-console:8082' \
ENROLLMENT_TOKEN='<from the console>' sh
Run it as root on the application server. It installs one static binary — CGO-free, so one file runs on Debian, Ubuntu, RHEL, Rocky, Alma and SUSE — creates an unprivileged user, writes a configuration file, and starts a confined systemd service.
Which sites this backend serves is declared, not guessed from its hostname. This is the one path in EdgeGuard that carries readings rather than inferences, and a guess at the front of it would undo that.
The token is good for one hour and one enrolment. It is stored hashed, cleared the moment it is spent, and removed from the file on that machine as well. A token that survives its use is a permanent key under another name.
Pass these alongside the two the console fills in:
| Variable | What it does |
|---|---|
CA_CERT=/path/to/ca.crt |
verify the console's certificate against this CA. Preferred. |
INSECURE=1 |
do not check the console's certificate at all. This machine's inventory then goes to whatever answers at that address. The console adds this itself when its own certificate is not publicly trusted. |
APP_ROOTS=/var/www,/srv/site |
read applications from these document roots instead of searching the usual places |
APP_SCAN=0 |
report system packages only. Reading a package database is cheap; reading a filesystem is not, and the owner of a backend may decline the second without declining the first. |
RUN_USER=nobody |
run as an existing user instead of creating one |
The collector authenticates by client certificate, the same way an agent does. The enrolment token exists only to get it one: the console mints the certificate and the key, the key crosses the wire once, and every report afterwards is mTLS. Note that mTLS proves the collector to the console and not the console to the collector — that is what
CA_CERTis for, and the collector says so on every start when it is running without one.
Click a collector's name. Two tabs, and the first is deliberately the same page as an agent's: the question "what needs patching here" does not change because the machine sits behind the proxy rather than being it.

CVEs with a fix and CVEs with no fix are counted separately rather than totalled, because they lead to different actions: one means run apt, the other means there is nothing to install and a mitigation is the only option left — which is where a WAF rule earns its place.
Counts are distinct CVEs. A source package's CVE appears once for every installed binary built from it, and counting those separately inflates the number without adding meaning: one machine's libreoffice has 29 installed binaries, so 14 issues would otherwise read as 406.
Click any count, or the package name, to see them.

The ones no upgrade clears come first, because they are the ones that need a decision rather than a command. Each carries Debian's own description, its urgency and its scope. Where Debian publishes no description the page says so, rather than leaving a blank that would make an undescribed issue look like a described one.
This is what an agent has no equivalent of.

| Column | Meaning |
|---|---|
| KIND | wordpress-core, wordpress-plugin, wordpress-theme, drupal-core, composer or npm |
| APPLICATION | the name the vendor knows it by, which is what an advisory is keyed on |
| VERSION | exactly as the file states it |
| KNOWN ISSUES | the worst severity known against this exact version, or nothing known |
| CVES | how many, click to read them |
| READ FROM | the file. This is the evidence, and it is checkable. |
Nothing known is an answer, not an absence — the row is listed either way, because dropping it would turn "nothing is known about this" into "it is not installed".
| Kind | Source |
|---|---|
| WordPress core | WordPress.org's own release list, which marks each of 959 releases latest, outdated or insecure |
| WordPress plugins and themes | the WordPress.org directory, which publishes a current version and no advisory list |
| Drupal core | drupal.org's supported branches and security releases |
| npm packages | the Retire.js database |
| Composer packages | Packagist's security advisories, which mirror FriendsOfPHP and GitHub's PHP advisories — the same source composer audit reads |
| System packages | the Debian Security Tracker |
A plugin or theme being behind the published version is not a vulnerability. The WordPress.org directory publishes a current version and no advisory list, so from there an old release with known problems and one with none look identical. The page says that in as many words, and shows "current is X" in grey rather than "fixed in X" in green — a badge is read before the sentence beneath it.
Two cases, both reported rather than hidden, because "we could not tell" is the one state an operator cannot discover by reading the page.
symfony/yaml at dev-my-fork is somebody's fork; a branch has no version, so no published range can be applied to it and composer audit cannot answer it either. One finding says so and names how many advisories went unchecked.composer audit on that backend.Neither resolves to unaffected. A package declared safe on the strength of a parser failure is worse than one reported as unknown.
Both are on the row, and the difference is what happens to the history.
Use revoke for a machine being decommissioned whose inventory is still worth having; use delete for one created by mistake.
On the collector's own page, and on Vulnerabilities alongside everything else. There, the System packages tab can be narrowed to agents or collectors, and every finding on the Web components tab says whether its version was reported by a collector or inferred from traffic — and can be filtered by that.
rpm command, since its database has had three incompatible backends across the versions in service) but their packages are not yet correlated: the Debian Security Tracker is the source, and there is no equivalent wired up for RHEL.