How the sidecar works
The sidecar exists to answer one question safely: how does a cloud service learn what a Wazuh fleet runs and sees without the fleet exposing anything? This page gathers the claims behind the answer in one place.
Read-only, as an absence
The sidecar's client for the Wazuh indexer has no method that writes. There is no PUT and no DELETE, and the only POSTs it can form are searches and counts. Read-only is a shape of the code rather than a promise in a document: nothing is installed into Wazuh, nothing is written to the cluster, and Pharos never creates a user, because creating one would be a write.
Three connections, all outbound
| Connection | Direction | Purpose |
|---|---|---|
| The Wazuh indexer API | From the host to the fleet's indexer | Everything the sidecar reports: the alert stream, the findings Wazuh already computed, the package inventory, the state collections and, on Wazuh 5.x, the agent census |
| The Wazuh manager's server API | From the host to the fleet's manager, Wazuh 4.x only | The agent count and roster, which 4.x keeps nowhere else. Its own certificate trust, separate from the indexer's |
| Pharos | From the host out over HTTPS | The reports, and the answers to them |
Nothing is inbound: no port is opened on the host and no Pharos address ever needs to reach it. The Wazuh login for the first two connections is typed in Pharos, carried to the plugin by Wazuh Fleet, and not kept by Pharos. A native sidecar keeps its login in a root-only file on the host. The registration token is the one value Pharos issues, exchanged once for a per-manager credential and held server-side only as a hash. See Install the sidecar from Wazuh Fleet.
What is sent, and how often
The sidecar asks Pharos for its reporting policy at start, so the cadences below are the service's and can change without a new binary.
| Report | Cadence | What it carries |
|---|---|---|
| Alert values | Every 5 minutes | The values worth checking against the indicator corpus, from a short list of alert fields, with the agent, the rule and a digest of the alert |
| Heartbeat | Every 10 minutes | The agent count and roster, the Wazuh version and what the sidecar could read |
| Findings | Every hour | The vulnerable packages the fleet's own Wazuh already reported: agent, CVE, package and version |
| File hashes | Every 30 minutes | The distinct hashes of files the integrity monitor saw change. Only matches are kept. A miss leaves no trace |
| Inventory | Every 6 hours | The package diff since the last accepted report, or nothing when nothing moved |
Alert values and findings stop when the workspace reaches its monthly limit, because they are what produce signals. Heartbeats and inventory keep running, so a fleet that is merely over budget stays visible rather than reading as an outage. See Signals.
Automatic updates
The Fleet plugin is updated by Fleet, on Fleet's own rollout schedule, and carries no timer of its own. See Install the sidecar from Wazuh Fleet.
A native sidecar carries a daily timer that keeps it current. The timer was on unless it was left out at install time.
The timer runs as root, once a day with up to six hours of jitter. It downloads the published binary for the release channel, verifies it against the published checksum, and replaces the sidecar in place before restarting it. It follows the channel wherever it points, which includes moving the binary backwards if the channel is rolled back to an earlier release. To patch the sidecar on the schedule the host already uses instead, disable the timer:
sudo systemctl disable --now pharos-sidecar-upgrade.timer
The updater only ever replaces the binary. It touches no credential and no configuration file, and a checksum that does not match stops it with the running binary left in place.
What never leaves the network
The alert fields the sidecar reads are an explicit list rather than a sweep of the document: source and destination addresses, DNS query and answer names, URLs, file and process hashes, the TLS server name, and their equivalents in Wazuh's own decoders, Sysmon events and file integrity monitoring. An extractor that walked the whole alert would find the fleet's hostnames, its internal DNS suffixes and its employees' mail domains, and it would send them, which is why the list is short on purpose.
Every value is then classified on the host, before anything is queued. Private
address space, loopback, link-local and multicast addresses, the documentation
and benchmarking ranges, carrier-grade NAT and the other reserved blocks are
dropped on the spot, and so are localhost, any hostname with no dot, and
anything ending in an internal suffix such as .local, .internal, .corp,
.lan, .home or .test. Private space is not filtered out of the request:
it is never put into one.
The sidecar's local state file holds its credential and its read positions. Its cache of values already checked stores digests rather than values, so a state file attached to a support ticket carries no record of what the fleet's hosts connected to. The registration token is not in it: it was used once and never stored.
Inventory sharing is on by default and switchable per manager, and it is the most sensitive thing Pharos asks for: the list of packages the fleet's hosts run. Turning it off stops coverage and the fleet watchlist for that manager and changes nothing about its alert stream. See Fleet exposure.
What the manager's page shows
Each manager's page is the account of what the sidecar read, so the console shows what Pharos looked at, not only what it kept.
- Sync, Operating system, Agents and Observes: when the sidecar last reported, the Wazuh version it found, the agent census, and whether the alert stream is readable at all.
- Inventory sharing: whether this manager shares its packages, how many, when the inventory was last updated, and the switch an admin uses.
- Last scan: every state collection the manager holds, with how many documents were checked and how many Pharos stored. Only what matches the corpus is stored. The rest is counted and discarded.
- Coverage: the CVEs naming a package this manager reports installed.
- Agents on file: the roster, each host opening onto its own page.
- What its alert stream produced: the indicator sightings on this manager, grouped by value.
A panel that is empty because the cluster refused a read says so, because "refused" and "genuinely nothing there" produce the same empty panel and mean opposite things. For the same reason, an agent count the sidecar could not establish is reported as unknown rather than as zero.