Connect the osquery agent to a controller

In the basic tutorial you deployed the osquery charm and confirmed that the osqueryd daemon was installed. In this tutorial you’ll finish the deployment by connecting the agent to an osquery controller, which supplies the agent’s configuration (query schedules, telemetry rules, and query tasks) and collects its logs.

What you’ll need

  • The deployment from the basic tutorial.

  • The connection details for an osquery controller:

    • The controller’s hostname or URI.

    • The environment UUID assigned to your fleet.

    • An enrollment secret.

    • Optionally, the TLS certificates used to authenticate to the controller, if your controller is configured to require them.

To learn how to provision an environment and obtain these values, see how to enroll the agent with a controller.

What you’ll do

  • Point the agent at a controller.

  • Provide the enrollment secret through a Juju secret.

  • Optionally, provide the TLS certificates.

  • Verify that the agent enrolls.

Point the agent at a controller

The agent needs to know the controller’s address and the environment UUID for your fleet. Set both with juju config:

juju config osquery \
  controller-uri=<controller-uri> \
  controller-env-uuid=<controller-env-uuid>

The controller-uri sets the TLS hostname the agent connects to, and the controller-env-uuid is expanded into the per-environment enrollment, configuration, logging, and distributed-query endpoints. Like the charm’s other options, these map directly to the underlying osqueryd flags; see the Configurations reference for the full mapping.

Provide the enrollment secret

The enrollment secret authenticates the agent to the controller during enrollment. Because it’s sensitive, it’s delivered through a Juju secret rather than a plain configuration value.

The enrollment secret is optional, but without it a controller that requires one will reject the agent.

Create the secret and grant the charm access to it:

secret_id=$(juju add-secret osquery-enroll-secret token=<your-enrollment-secret>)
juju grant-secret "$secret_id" osquery
juju config osquery enroll-secret="$secret_id"

Provide the TLS certificates (optional)

Mutual TLS is optional and most deployments don’t use it: the enrollment secret above is the common way to authenticate the agent. Only provide certificates if your controller is configured to require them.

If your controller presents a publicly trusted certificate, you don’t need to set tls-server-certs at all; the agent already verifies the controller against its bundle of publicly trusted certificate authorities. Provide it only to pin a private or self-signed certificate authority.

When they’re needed, the .pem files must be generated beforehand and registered with the osquery controller. Generating and registering them is out of scope for this tutorial. Once you have them, provide the server CA, the client certificate, and the client key as file-backed configuration options:

juju config osquery \
  tls-server-certs="$(cat server-ca.pem)" \
  tls-client-cert="$(cat client.pem)" \
  tls-client-key="$(cat client-key.pem)"

Verify that the agent enrolls

Watch the status until the charm settles into active:

juju status --watch 2s

Once the configuration is complete and valid, the charm renders the osquery flagfile, restarts osqueryd, and the agent enrolls with the controller. You can confirm the daemon is running on the host with:

juju ssh ubuntu/0 systemctl status snap.c-osquery.osqueryd

You should see the service reported as active (running):

● snap.c-osquery.osqueryd.service - Service for snap application c-osquery.osqueryd
     Loaded: loaded (/etc/systemd/system/snap.c-osquery.osqueryd.service; enabled; vendor preset: enabled)
    Drop-In: /etc/systemd/system/snap.c-osquery.osqueryd.service.d
             └─override.conf
     Active: active (running) since Mon 2026-08-25 10:00:00 UTC; 1min ago
   Main PID: 12345 (osqueryd)
      Tasks: 8 (limit: 4915)
     Memory: 20.0M
        CPU: 250ms
     CGroup: /system.slice/snap.c-osquery.osqueryd.service
             ├─12345 /snap/c-osquery/2/opt/osquery/bin/osqueryd --config_path /var/snap/c-osquery/common/etc/osquery/osquery.conf ...
             └─12346 /snap/c-osquery/2/opt/osquery/bin/osqueryd --config_path /var/snap/c-osquery/common/etc/osquery/osquery.conf ...

Clean up the environment

Once you’re done, you can remove the model and everything in it:

juju destroy-model osquery-tutorial --destroy-storage

If you used concierge, you can tear down the whole environment with:

concierge restore

Next steps

To learn how to keep your deployment healthy, see the how-to guides, in particular how to troubleshoot.

To understand the concepts behind what you just configured, see the charm design and security explanations, and the cryptographic overview.