Source overview
chainguard-dev/osquery-defense-kit
Production-ready osquery detection queries organized by ATT&CK technique.
chainguard-dev-osquery-defense-kit
· osquery SQL
· upstream repo ↗
· Apache 2.0
How detections work here
osquery exposes the state of an endpoint as SQL tables — processes, users,
listening_ports, file, launchd. A query is a SELECT against those
tables, and these queries are packaged into osquery query packs that run on a
schedule.
That makes this periodic state polling, not streaming detection. A query runs
every N seconds and sees whatever is true at that instant. Anything that starts
and exits between two runs is invisible, which is why so many of these queries
join processes to its parent and grandparent — reconstructing what happened
from what is still running.
Detection is the result set being non-empty. There is no condition clause and no severity expression: if the query returns rows, that is the finding, and the returned columns are the evidence.
How rules are written
Plain SQL with a comment header carrying the metadata osquery packs cannot:
-- Programs running as root with a relative path
--
-- references:
-- * https://www.microsoft.com/...
--
-- tags: transient process state
-- platform: posix
SELECT p0.pid, p0.path, p0.name, p0.cmdline, ...
FROM processes p0
LEFT JOIN file f ON p0.path = f.path
The tags line drives deployment: upstream tooling derives each query's polling
interval from its tags, so transient queries run far more often than ones
checking durable state. The platform line scopes it to posix, darwin, linux or
windows.
Reading a rule on this site
The whole SQL body is the rule. Platform comes from the header comment, which is why this source populates platforms but very little else.
ATT&CK reads as a dash here, not zero. Upstream files detection queries into directories named after ATT&CK tactics, but that is path convention rather than a field in the query, and we do not currently extract it. The absence is ours, not the ruleset's — coverage is not missing, it is unmapped.
Note what is indexed: of 270 queries, 163 are under detection/, 101 under
incident_response/, 5 under policy/ and 1 under vulnerabilities/. The
incident_response queries are evidence collection tuned for periodic gathering
during a response — they are meant to return rows routinely and are not
detections. Check source_path before treating a query as an alert candidate.
Gotchas
- Nearly 40% of what you see here is incident-response collection, not
detection.
source_pathis the only way to tell them apart on this site. - These queries return wide result sets by design — parent and grandparent process context, hashes, file modes. That is deliberate evidence gathering, not an unfiltered query.
- Polling means coverage gaps between runs. A query is only as good as the interval it is deployed at, and that interval is not in the query.