Charm design¶
osquery is endpoint security monitoring software: its purpose is to observe the
host it runs on. That job only makes sense on the same machine as the workload
being monitored, so the charm is designed as a
subordinate charm
that attaches to a principal application over the generic juju-info
interface. This lets a single osquery application monitor any principal machine
charm without that charm needing to know anything about osquery.
It’s a machine charm rather than a Kubernetes charm because osqueryd runs as
a host daemon that inspects operating-system state — processes, sockets,
packages, and kernel events — which requires direct access to the host rather
than a container sandbox.
Installing from a snap¶
The charm installs the Canonical SecOps fork of osquery from the
c-osquery snap, on the channel set in
snap-channel, and runs the osqueryd daemon as the snap’s
snap.c-osquery.osqueryd systemd service. A single snap build serves every
supported Ubuntu base and is the artifact the fork tests before each release.
The snap uses classic confinement because osquery’s eBPF backend needs
host-wide tracing privileges that no strict-confinement interface grants.
Configuration-driven reconciliation¶
The charm has no actions. Instead, all of its behavior is driven by configuration, and it applies that configuration through a holistic reconcile loop. Every relevant Juju event runs the same idempotent handler, which ensures osquery is installed, renders the configuration into the osquery flagfile, writes the file-backed secrets, restarts the daemon if needed, and reports status.
This design keeps the charm simple and predictable: there’s exactly one code path
that brings the host to the desired state, so the charm behaves the same way
regardless of which event triggered it. If a required value is missing, the charm
reports a blocked status rather than failing, making misconfiguration easy to
diagnose. See the charm architecture documentation for
the module-level breakdown.
Separating workload logic from Juju logic¶
The host-facing workload logic (installing the snap and managing the service) lives in a module that deliberately imports nothing from Ops or Juju. This separation makes the workload logic straightforward to unit test in isolation and keeps the charm’s Juju-facing concerns (events, configuration, status) cleanly separated from its host-facing concerns.
Talking to a controller instead of Juju relations¶
An osquery fleet is coordinated by a central osquery controller that owns the query schedules, telemetry rules, and log storage. The charm connects each agent to that controller directly over TLS rather than modelling the controller as a Juju relation. This keeps the charm aligned with how osquery fleets are operated in practice and avoids duplicating the controller’s responsibilities in Juju.