Threat Intelligence

Osquery Packs: Prebuilt Detection and Compliance Query Packs

Osquery packs bundle scheduled queries into shippable units. What ships by default, how discovery queries work, and why the stock packs are a starting point, not a program.

Chris Seymour, Co-Founder and Principal at Artemes AI
Chris Seymour
Co-Founder, Principal
Jul 20, 2026 10 min read
Abstract visualization of osquery query packs feeding a scheduled detection pipeline

Osquery packs are not a detection program. They are a starting point that someone still has to own.

An osquery pack is a JSON file that groups scheduled queries under one name. That is the whole idea. The project ships a handful of them, teams pass them around, and a lot of deployments treat the default set as finished security content. It is not finished. It is a well organized draft written for a general audience, and the gap between that draft and your environment is where the value lives.

This matters because packs are the unit most teams use to go from playing with osquery on one laptop to running it across a fleet. Get the packs right and you have versioned, reviewable detection content. Get them wrong and you have a schedule that burns CPU and analyst hours to tell you things you did not ask about.

Infographic

How a pack becomes a running schedule

A pack is a file of queries. A discovery query decides whether those queries run on this host at all.

The path from a pack file to differential logsA left to right flow with four stages. Stage one, a pack file containing a discovery query and a set of scheduled queries. Stage two, a discovery gate that runs the discovery query and checks whether it returns any rows. If it returns nothing, the pack is skipped on that host. If it returns rows, the pack queries join the schedule. Stage three, the daemon runs the queries on their intervals. Stage four, only changed rows are emitted as differential logs.1 · Pack filediscovery: [ ... ]queries: {crontab ...listening ...}2 · Discovery gateDoes the queryreturn rows?Yes: queries runNo: pack skipped3 · ScheduleDaemon runseach query onits interval4 · LogsOnly changedrows emittedThe discovery gate is why a well built pack costs almost nothing on hosts it does not apply to

What is an osquery pack?

In an osquery configuration, a pack is a top level key that maps a pack name to a set of queries. Each query carries its own SQL, an interval in seconds, and optional selectors like platform or minimum version. When the daemon loads the config, every query in an active pack joins the schedule as if you had written it inline.

The only trick worth remembering is naming. A query called suid_bins inside a pack called incident-response shows up in your logs as pack_incident-response_suid_bins. The pack name becomes part of the scheduled query identifier, which is how you trace a noisy log line back to the file that produced it. You can change the joining character with the --pack_delimiter flag, and the mechanics are laid out in the official osquery configuration docs.

If you have not written scheduled queries yet, start with our guide to writing osquery queries, then come back. A pack is only as good as the queries inside it, and a pack full of expensive selects will get denylisted by the watchdog no matter how neatly it is organized.

What packs ship with osquery?

The project publishes a set of reference packs in the /packs directory of the osquery repository, bundled alongside the installers. The recurring names you will see are:

  • incident-response: process, socket, startup, and login state useful when you are chasing something down.
  • it-compliance: system settings and configuration facts an auditor tends to ask about.
  • vuln-management: package and kernel inventory meant to be paired with an outside vulnerability feed.
  • osx-attacks and windows-attacks: platform specific indicators drawn from known techniques.
  • hardware-monitoring, osquery-monitoring, and ossec-rootkit: device inventory, self health, and classic rootkit checks.

Meta released these packs publicly back in July 2015, framing them as high signal queries worth running, and the collection has barely moved since. You can read the original announcement on the Engineering at Meta blog. Useful history, and a warning. Content written for a 2015 fleet is a reference, not a plan for the machines you run today.

How do you add osquery packs to your config?

There are three ways to attach a pack, and they trade convenience for control. The simplest is a file path. Point the pack name at a JSON file on disk and osquery loads it:

{
  "packs": {
    "incident-response": "/opt/osquery/packs/incident-response.conf",
    "vuln-management": "/opt/osquery/packs/vuln-management.conf"
  }
}

The second way is a glob. Drop every pack in one directory and let osquery pick them all up, naming each pack after its filename:

{
  "packs": {
    "*": "/opt/osquery/packs/*"
  }
}

The third way is inline JSON, where the pack content lives directly in the config. Inline is how you get selectors and discovery working, and it is the form worth understanding:

{
  "packs": {
    "mysql_watch": {
      "platform": "linux",
      "discovery": [
        "SELECT pid FROM processes WHERE name = 'mysqld';"
      ],
      "queries": {
        "mysql_processes": {
          "query": "SELECT name, path, pid FROM processes WHERE name = 'mysqld';",
          "interval": 600,
          "description": "Track running MySQL processes."
        }
      }
    }
  }
}

The platform, version, and shard keys apply to the whole pack, so you can restrict a Windows pack to Windows or slow roll a new pack to a percentage of hosts before it goes fleet wide. That last one is underused. Shipping a new pack to 5 percent of machines first is the difference between a contained mistake and a fleet wide incident of your own making.

What are discovery queries and why do they matter?

Discovery is the feature that makes packs worth using at scale. A discovery query is a small SQL check at the top of a pack. If it returns at least one row, the pack runs on that host. If it returns nothing, the pack sits dormant and costs nothing.

Think about what that solves. You want to monitor MySQL, but you do not have a reliable list of which hosts run MySQL, and engineers install things you never approved. Without discovery, you either run the MySQL queries everywhere and waste cycles, or you maintain a fragile inventory in your configuration management. With discovery, the pack asks the host directly: are you running mysqld? Only the hosts that answer yes take on the work. osquery refreshes these checks every 60 minutes by default, tunable with pack_refresh_interval.

Multiple discovery queries short circuit, which is a handy pattern when a pack depends on an extension. Put a cheap "is the extension loaded" check first, and the expensive checks never run on hosts where the table does not exist. Small detail, real savings.

Where do the default osquery packs fall short?

Here is the part vendors and starter guides skip. The shipped packs are aging reference material, and treating them as a security program creates three specific problems.

First, the intervals and queries were tuned for a fleet that is not yours. Many default queries run once a day and select entire tables. That is fine on a workstation and painful on a busy database server. You inherit someone else's assumptions about acceptable load unless you read every line.

Second, the vuln-management pack does not detect vulnerabilities. Read it and you find deb_packages, rpm_packages, os_version, and kernel_info, each labeled with a note that it is useful "with the help of a vulnerability feed." The pack gives you inventory. Turning inventory into a real finding is a separate job, and we cover it in using osquery for vulnerability detection.

Third, a pack produces rows, not decisions. This is the cost nobody budgets. Suppose a compliance pack ships 40 queries and 8 of them fire something worth a human glance every day. If an analyst spends 10 minutes on each, confirming most of it is nothing, that is 80 minutes a day. Call it 7 hours a week, most of one analyst, spent clearing a vendor default nobody tuned. The same signal to noise math shows up across security tooling, and we walk through it in reducing false positives in vulnerability management.

How should you actually run osquery packs?

Treat the shipped packs as a menu, not a meal. A short operator sequence keeps them honest:

  • Start from a reference pack, but copy it into your own repository. Never run someone else's file unread.
  • Delete every query you cannot explain in one sentence. Unexplained queries are just future noise.
  • Add a discovery query so the pack only wakes up where it is relevant.
  • Set intervals against your slowest hosts, not your laptops. Test on a shard before you trust the number.
  • Version the pack in source control so a change to detection content is a reviewable commit, not a mystery.

That last habit is why packs beat a pile of inline queries. A pack is a shippable unit. When you run osquery across many machines through a central manager, packs are how you distribute and update detection content cleanly, a workflow we get into in osquery fleet management. The daemon side of this, and how scheduled packs differ from ad hoc shell work, is covered in osqueryi vs osqueryd.

The stakes for keeping this content current are not academic. CISA's Known Exploited Vulnerabilities catalog crossed 1,480 entries at the end of 2025, growing about 20 percent in a single year per SecurityWeek's reporting. The questions worth asking on your endpoints change as fast as that list does. A pack you wrote and forgot is a pack watching for last year's problem.

Frequently asked questions

Where are the default osquery packs installed?

The reference packs ship alongside the installers and live in the /packs directory of the osquery repository. On installed systems they usually land near the osquery share directory. Most teams stop using the on disk copies and manage their own versions in source control instead.

Can a pack slow down my endpoints?

Yes, if it schedules expensive queries at short intervals. The built in watchdog will denylist a query that exceeds resource limits, but a badly tuned pack still wastes cycles before that happens. Set intervals for your heaviest hosts and slow roll new packs with the shard selector.

Do osquery packs detect CVEs on their own?

No. Packs like vuln-management collect package and version inventory. Mapping that inventory to specific CVEs requires an external vulnerability feed and correlation logic that osquery does not include.

What is the difference between a pack and the schedule?

The schedule is the flat list of queries osquery runs. A pack is a named bundle of queries, with optional selectors and a discovery gate, that gets merged into the schedule when its conditions are met. Packs are for organizing and distributing; the schedule is what actually executes.

The takeaway

Download a reference pack this week, but do not deploy it. Read it line by line, cut what you cannot justify, add a discovery query, and commit it to your own repository with intervals sized for your real hardware. A pack you have read and trimmed is worth more than ten you inherited and hoped about. The organizing is easy. Owning what the pack asks, and what you do with the answers, is the work.

Artemes AI

See which of your findings actually matter

Artemes AI combines deep endpoint context with AI-driven analysis to show which findings are actually exploitable on your hosts—not just everything a scanner can list. We are onboarding early access teams now.

Chris Seymour, Co-Founder and Principal at Artemes AI

Chris Seymour

Co-Founder, Principal

Chris writes about vulnerability prioritization, exploitability, AI-assisted remediation, and the engineering realities of turning scanner output into remediation decisions.

Osquery
Blue Team
Security Automation
Found this useful? Share it.