Exclusions
An exclusion stops a forwarder collecting files under a path. That is sometimes exactly right and always a place Stairwell cannot see, so keep them narrow.
An exclusion is a path glob that tells a Stairwell forwarder to skip files matching it. You create exclusions in an environment and attach them to a policy, and every forwarder running that policy stops collecting under those paths. They override the policy's extension list, so a .exe inside an excluded directory is not collected regardless of the fact that .exe is on the collection list.
Exclusions exist because some paths genuinely should not be collected. They are also the one control in Stairwell that reduces what you can see, so the rest of this page is about spending them well.
What does an exclusion actually cost me?
An excluded path is a place Stairwell has no record of. That is the whole of it, and it is worth stating plainly because the cost arrives later than the benefit.
The benefit is immediate and visible: less upload traffic, a shorter backscan, less file activity on a busy host. The cost is invisible until an investigation needs the path. If a file lands in an excluded directory, then Stairwell holds no copy of it, so it cannot be scanned by a YARA rule you write next month, cannot be compared against a threat report published next quarter, does not appear in prevalence counts, and produces no sighting telling you it was ever on that machine. Retroactive analysis is the thing Stairwell is for, and an exclusion is a decision to give it up for one path in advance and permanently.
Two properties of that cost matter for how you write the pattern:
- It is not retroactive in your favour. Removing an exclusion later starts collection going forward. It does not recover what was on disk while the exclusion was in place unless those files are still there when a backscan next runs.
- It is exactly as wide as the glob.
**/*.jsonexcludes every JSON file on the machine, not the ones in the build directory you were thinking of. The pattern is the whole of the policy.
Attackers stage payloads in writable directories with high legitimate churn, because those are the directories nobody watches. Those are also the directories that show up first on a list of things to exclude for performance. That overlap is the reason to prefer a narrow pattern even when a broad one would be less work.
How do I choose an exclusion narrowly?
Four questions, in order. Each one is a chance to make the pattern smaller.
- Can I exclude a directory instead of a file type?
/var/lib/containers/storage/overlay/**is a specific place.**/*.sois every shared object on the host, including the one that got dropped into a user's home directory. Anchor to a path whenever you can. - Can I use "Do not scan" instead of "Do not upload"? See the next section. It keeps real-time visibility and only skips the path during scheduled scans, which is usually where the cost actually is.
- Does this need to apply to the whole fleet? An exclusion is attached to a policy, and a policy is attached to a group. Put a developer-machine exclusion on a developer-machine group, not on the default policy that every asset inherits. This is the single most effective way to keep an exclusion narrow, because it bounds it by machine as well as by path.
- What would I want to have collected from this path if this machine turned out to be the intrusion? If the honest answer is "the executables, not the ten thousand intermediate object files", the pattern should name the intermediate files.
A worked example. A build server's Bazel cache is a real problem: enormous, churning constantly, and almost entirely intermediate output. Excluding /** on build servers solves it and blinds you to the build servers. Excluding the cache directory specifically solves it and leaves the rest of the machine visible. Excluding source file extensions across the whole fleet solves it and takes with it every script in every user directory on every machine you own.
What is the difference between "Do not upload" and "Do not scan"?
They are the two exclusion types, and choosing the right one is most of what this page is asking you to do.
| Type | What it does | When to choose it |
|---|---|---|
| Do not upload | The forwarder never uploads a file whose path matches, from any source of file activity | The path must not leave the machine at all: a directory subject to a data handling rule, a volume you have been told not to read |
| Do not scan | Files under the path are skipped during the initial and scheduled backscans. If a matching file is created, modified, or executed, it is still uploaded | Almost every performance-motivated exclusion |
"Do not scan" is the one to reach for by default, and the reason is worth understanding rather than accepting. The expensive part of a large, churning directory is the scan that walks all of it. The valuable part is knowing when something new appears in it or something there runs. "Do not scan" gives up the first and keeps the second. It is a much smaller blind spot than "Do not upload" for the same reduction in scan cost.
How do I create an exclusion?
Exclusions live at the environment level, then get attached to one or more policies. Create the exclusion first.
- In Settings, under Environments, open Asset exclusions.
- Select the environment with the environment filter at the top of the list.
- Click Create exclusion.
- Choose the Exclusion type: Do not scan exclusion or Do not upload.
- Choose the Operating System: macOS, Windows, or Linux. This field is not optional and it is the one people get wrong. Read the next section before you pick.
- Enter the Path glob. Glob syntax, for example
**/*.foo. - Enter a Description. It is optional and you should write one anyway: six months from now the description is the only record of why a path is invisible.
- Save.
Then attach it to the policies that should honor it:
- In Settings, under Environments, open Asset policies and edit the target policy.
- Open the Exclusions tab.
- Click Add exclusion, select the exclusions to attach, and save.
An exclusion attached to no policy does nothing. An exclusion attached to the default policy applies to every asset in the environment.
Why is my exclusion not taking effect?
Four causes, in the order they actually occur.
- The operating system does not match. An exclusion carries a single OS, and it is applied only to assets running that OS. A Windows path glob saved with the OS set to macOS is silently inert on every machine in your fleet. If you need the same logical exclusion on two platforms, create two exclusions. The default in the dialog is macOS, so a Windows path saved without changing that field is the most common version of this mistake.
- It is not attached to a policy the asset has. Check which policy the asset's group carries.
- The path does not match the glob. Globs match the path as the forwarder sees it, so a Windows pattern needs Windows separators and a Linux pattern needs Linux separators. Test on one host before you attach it to a fleet-wide policy.
- You are expecting it to stop a sighting rather than an upload. With a "Do not scan" exclusion, an execution or modification under the path still produces an upload. That is the design, not a fault.
How do exclusions behave when an asset is in more than one group?
They add up. An asset in two groups gets the union of both policies' exclusions, so the effective exclusion set is the most restrictive combination rather than one policy winning. This is the opposite of how the extension list behaves, where an asset in two groups collects the union of both extension lists. Both rules point the same way in practice: stacking groups collects fewer paths and more file types.
The consequence to watch for: adding a machine to an extra group can only ever make it less visible, never more. Groups and Policies covers the full stacking rules.
When should I use an intake filter instead?
When the file must not be stored no matter how it arrived. An exclusion is honored by forwarders. An intake filter is enforced on Stairwell's side and applies to forwarder uploads, API uploads, and manual uploads from the console alike.
The tradeoff is where the work happens. An exclusion means the forwarder never touches the file, so it also saves the local disk and CPU cost of opening and hashing it. An intake filter means the forwarder still opens and hashes the file and then the upload is refused, so it protects the vault but not the host. Use an exclusion for performance, an intake filter for a rule about what may be stored, and both when you mean both.
What should I read next?
- Recommended Exclusions, for the specific paths that most often earn an exclusion, with the reason for each.
- Intake Filters, for the server-side control and how it differs.
- Create and Edit Policies, for attaching exclusions to the right policy rather than to everything.
Updated 17 days ago