AI agents: see /llms.txt for a full index of this site, or /llms-full.txt for concatenated documentation.

Workshop Docs

Enterprise control plane for Santa. Manage rules, approvals, telemetry, and policies across your macOS fleet.

Workshop Docs
View chapters on this page

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 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.

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 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 page:

Sub-fieldEvent type
event.ExecutionProcess execution
event.ForkProcess fork
event.ExitProcess exit
event.CloseFile close
event.RenameFile rename
event.LinkHard link creation
event.UnlinkFile deletion
event.CloneFile clone
event.ExchangedataFile data exchange
event.FileAccessFile access policy hit
event.AuthenticationAuthentication attempt
event.LoginLogoutConsole login/logout
event.LoginWindowSessionGUI session events
event.OpenSSHSSH login/logout
event.AllowlistAllowlist additions
event.BundleBundle hash event
event.GatekeeperOverrideGatekeeper bypass
event.TCCModificationTCC modification
event.XProtectXProtect detection
event.ScreenSharingScreen sharing event
event.DiskDisk mount/unmount
event.LaunchItemLaunch item event
event.ProcSuspendResumeProcess suspend/resume
event.CodesigningInvalidatedCodesigning 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 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 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 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