RFDs/0012
Operational queries
Goal
Let operators ask a host a specific, read-only question on demand, such as "what is listening on this host" or "which services are failed", and get a typed answer without shell access. RFD 1 requires operational queries to be typed, read-only collector operations and never an alias for arbitrary shell execution. This RFD defines them on RFD 9's jobs.
What a query is
A query is an RFD 9 capability in the observe class
named query.<name>@<version>.
Its definition fixes:
-
a parameter schema, validated by Renga before the job is stored and again by the agent before it runs;
-
a result schema and a maximum result size;
-
a timeout;
-
a sensitivity:
inventory(no more revealing than an observation) orsensitive(reveals software versions, running services, or other detail an attacker would value).
The agent implements each query natively, through procfs, netlink, or systemd’s D-Bus interface. Where a query must run a program, the argument vector is fixed in the agent’s code and never includes text from the request. There is no query that takes a command, a path to execute, or a script.
First queries
| Capability | Answers | Sensitivity |
|---|---|---|
|
Listening TCP and UDP sockets with their process names |
sensitive |
|
systemd units and their active, failed, and enabled states |
sensitive |
|
Filesystem capacity and use, beyond the inventory snapshot |
inventory |
|
The routing table per routing domain |
inventory |
|
Clock synchronization source, offset, and status |
inventory |
|
Installed packages and versions, bounded and filterable by name |
sensitive |
These are the prefilled options every host offers with no extra software. They stay native so a plain installation answers the common questions.
osquery backend
Renga does not grow a bespoke query language. For anything beyond the named queries, hosts run osquery, which already models hundreds of tables across Linux, macOS, and Windows.
The agent never runs osquery itself. It talks to a locally managed osqueryd
over osquery’s extensions socket, which the operator makes reachable by the
agent’s account. osquery keeps its own privileges, the agent’s sandbox does not
change, and the agent reports the backend’s status (available,
not_permitted, not_present) on the Collectors page like any other source.
When the backend is available, named queries may be answered by fixed SQL that
ships with the agent’s version. For example, query.packages@1 reads osquery’s
package tables. The result still matches the query’s own schema, and the
native implementation is used whenever osquery is absent.
Ad hoc SQL
query.sql@1 runs an operator-written osquery SELECT and is the one query
whose text comes from the request. Free-form SQL is not typed in the
RFD 1
sense, because some osquery tables read arbitrary files (file, yara,
augeas), make network requests (curl, curl_certificate), or copy files off
the host (carves). It is therefore bounded differently from the named
queries:
-
It is always
sensitive, off by default in both the organization and the agent’s[jobs]policy, and limited to owners and admins. -
Dangerous tables are excluded by osquery itself through its
disable_tablesflag, not by parsing SQL in Renga or the agent. Before each run the agent reads the daemon’s flags and refuses with a policy reason unless every table on the agent’s deny list is disabled. -
Results are a bounded table: column names and string values, with row and byte limits and the same timeout as other queries.
The UI offers query.sql@1 only on hosts whose agent reports the backend
available, and otherwise explains that installing osquery unlocks it.
Authorization
Queries are off until an organization enables them, and each can be enabled
separately. Owners and admins may run enabled queries. An organization may also
let members run inventory-sensitivity queries; sensitive queries stay with
owners and admins. The agent’s [jobs] policy must also enable each query; the
agent default enables only inventory queries.
Sensitivity also governs reading retained parameters, output, results, and events, not just requesting execution. Every job/detail/event endpoint, recent history, batch table, and export checks the reader’s current organization and sensitivity authorization. Sensitive payloads remain owner/admin-only even if a member can see generic job history; inventory results follow the current organization member-query policy. Having requested a job grants no permanent read access after authorization is revoked. Activity exposes only authorized summaries, never sensitive parameters or results through a generic feed.
Results
A query’s result is its job’s final event, bounded by the query’s maximum size and kept for the job retention period. Results are not observations: they never change canonical inventory, freshness, or findings. A question worth answering continuously belongs in the collector’s regular payload, not in a scheduled query.
Fan-out is a first-class use: running query.listening_sockets@1 across a
saved view answers "which hosts listen on port 23" as one batch whose results
appear as a table.
Decisions from review
-
The agent enables the
inventory-sensitivity queries by default, as RFD 9 does forobservecapabilities;sensitivequeries need an explicit[jobs]entry. -
query.packages@1ships in the first set as asensitivequery, so fleet-wide version questions are answerable by owners and admins. -
Named queries stay native as prefilled options; full query capability comes from osquery, which operators install and run themselves.
-
Ad hoc osquery SQL is a separate
sensitive, off-by-default query, with dangerous tables disabled in osquery itself.
User interaction
-
A resource’s Queries tab lists the queries its agent offers, runs one, and shows recent results with who ran them. Where the agent reports osquery available, it also offers an SQL editor for
query.sql@1. -
From a saved view, "Run query" fans out to every matching host and shows the batch’s results as they arrive.
-
Every run appears in activity with an authorized summary; parameters and results are visible only through sensitivity-authorized views.
Later
A natural-language interface may later sit on top of these queries as an LLM integration that drafts a named query or osquery SQL for the operator to review before it runs. It would add no new execution path and is left to its own RFD.
Rollout
-
Define the query capability shape, the sensitivity rule, and the organization settings.
-
Implement the first queries in the agent behind
[jobs]policy. -
Add the Queries tab and fan-out from saved views.
-
Add the osquery backend, osquery-backed named queries, and
query.sql@1.
Implementation
Progress is tracked in the implementation checklist.