---
title: "Filter Expressions - Workshop Docs"
description: "Filter Expressions - Enterprise control plane for Santa. Manage rules, approvals, telemetry, and policies across your macOS fleet."
doc_version: "1"
last_updated: "2026-05-22"
canonical: "https://northpole.security/docs/workshop/telemetry/filter-expressions"
---
# Telemetry Filter Expressions

Telemetry filter expressions are CEL expressions evaluated by Santa on the client before events are uploaded. They give you fine-grained control over which events are sent to your telemetry bucket — for example, to drop noisy event types entirely, exclude events from a specific binary, or redact sensitive values like tokens out of an event before it leaves the host.

Filter expressions are configured per-tag in Sync Settings and apply to every event Santa produces. They are evaluated locally on the host, so events that are filtered out never reach Workshop or your cloud storage bucket.

Filter expressions can also be set directly in the Santa configuration profile via the [`TelemetryFilterExpressions`](https://northpole.dev/configuration/keys/#TelemetryFilterExpressions) key — useful when you want to apply a baseline filter through MDM rather than through Workshop sync.

For a full reference of the CEL environment Santa exposes — including all event types, fields, and built-in functions — see [Santa’s telemetry documentation](https://northpole.dev/features/telemetry/).

## Configuration

Telemetry filter expressions are managed on the **Telemetry** tab of the Sync Settings editor. Each tag may define any number of expressions; the effective list for a host is determined by the same tag-precedence rules used for all other sync settings.

Hosts must be enrolled in a tag whose telemetry configuration has telemetry **enabled** for expressions to take effect. See the [Telemetry overview](https://northpole.security/docs/workshop/telemetry) for how telemetry collection is set up.

## Expression Semantics

Each filter expression is evaluated once per event. The expression’s boolean result determines whether the event is kept. Multiple expressions are combined so that an event is kept only when **all** expressions agree to keep it — in other words, expressions act as an AND of independent filters.

Expressions also have access to two Santa functions for scrubbing sensitive values out of an event in-place before it is uploaded:

-   `hash(value, regex)` — replaces the regex’s captured group with a hash of the matched substring. The original value never leaves the host, but the hashed value can still be used to correlate the same secret across events.
-   `redact(value, regex)` — replaces the regex’s captured group with a fixed redaction marker. Use this when you want to scrub the value entirely with no correlation across events.

Both functions return `true`, so they compose naturally inside boolean expressions like `exists()` — the filter can match on a sensitive value and scrub it in a single pass.

## The `event` Variable

The top-level variable available to a filter expression is `event`. It is a union of all Santa event types; exactly one sub-field is populated per event. The sub-fields use PascalCase and correspond to the event types described on the [Schema](https://northpole.security/docs/workshop/telemetry/schema) page:

Sub-field

Event type

`event.Execution`

Process execution

`event.Fork`

Process fork

`event.Exit`

Process exit

`event.Close`

File close

`event.Rename`

File rename

`event.Link`

Hard link creation

`event.Unlink`

File deletion

`event.Clone`

File clone

`event.Exchangedata`

File data exchange

`event.FileAccess`

File access policy hit

`event.Authentication`

Authentication attempt

`event.LoginLogout`

Console login/logout

`event.LoginWindowSession`

GUI session events

`event.OpenSSH`

SSH login/logout

`event.Allowlist`

Allowlist additions

`event.Bundle`

Bundle hash event

`event.GatekeeperOverride`

Gatekeeper bypass

`event.TCCModification`

TCC modification

`event.XProtect`

XProtect detection

`event.ScreenSharing`

Screen sharing event

`event.Disk`

Disk mount/unmount

`event.LaunchItem`

Launch item event

`event.ProcSuspendResume`

Process suspend/resume

`event.CodesigningInvalidated`

Codesigning invalidate

Use the `has()` macro to test which sub-field is populated. Once you’ve gated on the event type, you can navigate into nested fields using the same names that appear on the [Schema](https://northpole.security/docs/workshop/telemetry/schema) page.

```
has(event.Execution) && event.Execution.Target.Executable.Path == '/usr/bin/yes'
```

## CEL Basics

Telemetry filter expressions use the same CEL language as [CEL rules](https://northpole.security/docs/workshop/rules/execution-rules#cel-rules) and CEL fallback rules. The following are commonly useful:

-   **Logical**: `&&`, `||`, `!`
-   **Comparison**: `==`, `!=`, `<`, `>`, `<=`, `>=`
-   **String functions**: `startsWith()`, `endsWith()`, `contains()`, `matches()`, `size()`
-   **List macros**: `exists()`, `all()`, `filter()`, `map()`, `size()`
-   **Optional field access**: `has()`

See [celbyexample.com](https://celbyexample.com) for a comprehensive CEL reference.

## Examples

### Keep only execution events

```
has(event.Execution)
```

### Drop executions from a noisy path

```
!(has(event.Execution) &&
  event.Execution.Target.Executable.Path.startsWith('/opt/homebrew/'))
```

### Redact a token-shaped environment variable

```
has(event.Execution) &&
  event.Execution.Envs.exists(e,
    e.startsWith("GITHUB_TOKEN") && hash(e, "GITHUB_TOKEN=(.*)"))
```

This expression matches execution events that carry a `GITHUB_TOKEN` environment variable and uses `hash()` with the regex `GITHUB_TOKEN=(.*)` to replace the captured value with a hash before the event is uploaded. The original token never leaves the host, but the hashed value can still be used to correlate the same token across events.

### Redact a token entirely

```
has(event.Execution) &&
  event.Execution.Envs.exists(e,
    e.startsWith("AWS_SECRET_ACCESS_KEY") &&
    redact(e, "AWS_SECRET_ACCESS_KEY=(.*)"))
```

Identical in shape to the `hash()` example, but uses `redact()` to replace the captured value with a fixed marker — appropriate when you don’t need to correlate the same secret across events.

### Drop a specific file-access policy from upload

```
!(has(event.FileAccess) && event.FileAccess.PolicyName == 'noisy-policy')
```

### Keep authentication events for failures only

```
!has(event.Authentication) || !event.Authentication.Success
```

## Validation and Rollout

Workshop stores expressions as plain strings and delivers them to hosts on the next sync. Validation is performed by Santa when it parses the configuration — an invalid expression is logged on the host and ignored, so test changes on a small tag before rolling them out widely.

A safe rollout pattern is:

1.  Apply the new expression to a single host or test tag.
2.  Confirm in your telemetry bucket that the expected events are kept, dropped, or redacted.
3.  Promote the expression to a broader tag once you’re satisfied.

## See Also

-   [Telemetry](https://northpole.security/docs/workshop/telemetry) — how to enable telemetry collection
-   [Schema](https://northpole.security/docs/workshop/telemetry/schema) — the field names referenced by `event.*`
-   [CEL Execution Rules](https://northpole.security/docs/workshop/rules/execution-rules#cel-rules) — CEL used for policy decisions
-   [Santa telemetry documentation](https://northpole.dev/features/telemetry/) — authoritative reference for the CEL environment exposed by Santa

## Sitemap

- [Home](https://northpole.security/index.md)
- [Workshop](https://northpole.security/workshop.md)
- [Santa](https://northpole.security/santa.md)
- [Features](https://northpole.security/features.md)
- [Cookbook](https://northpole.security/cookbook.md)
- [Docs](https://northpole.security/docs.md)
- [Blog](https://northpole.security/blog.md)
- [Glossary](https://northpole.security/glossary.md)
- [About](https://northpole.security/about.md)
- [Contact](https://northpole.security/contact.md)
