Skip to main content

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​

ConnectionDirectionPurpose
The Wazuh indexer APIFrom the host to the fleet's indexerEverything 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 APIFrom the host to the fleet's manager, Wazuh 4.x onlyThe agent count and roster, which 4.x keeps nowhere else. Its own certificate trust, separate from the indexer's
PharosFrom the host out over HTTPSThe 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.

ReportCadenceWhat it carries
Alert valuesEvery 5 minutesThe 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
HeartbeatEvery 10 minutesThe agent count and roster, the Wazuh version and what the sidecar could read
FindingsEvery hourThe vulnerable packages the fleet's own Wazuh already reported: agent, CVE, package and version
File hashesEvery 30 minutesThe distinct hashes of files the integrity monitor saw change. Only matches are kept. A miss leaves no trace
InventoryEvery 6 hoursThe 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 updater runs as root

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.

note

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.