Announcing Santa and Workshop 2026.9
Lockdown for developers, DNS rules, security key approvals, and much more
Annotate your build system once, and one fallback rule lets developers build, test and run their projects through it in Lockdown.
Santa and Workshop 2026.9 add two new building blocks for policy. Process annotations let a CEL rule mark a process and everything it starts, which makes Lockdown livable for developers: annotate the build system, and one fallback rule lets what it builds run under it. DNS rules answer a blocked lookup before the name resolves. This release also adds security key approvals, executable integrity checks, parent directory protection for file access rules, and a customizable Slack approval message.
Process Annotations
Lockdown is hardest on developers. A build writes and runs binaries that no rule has seen, with a toolchain that differs from project to project, and transitive rules only help once you know which tool in that toolchain to trust. Process annotations make Lockdown livable on a developer’s Mac. add_annotation() stamps a name on the process being executed, the processes it starts inherit it, and has_annotation() tests for it with a lookup.
Lockdown for Developers
Start with a CEL rule on your build system’s driver, Bazel in this example, that allows it and annotates it:
// Rule on bazel
add_annotation("bazel", ALLOWLIST)
add_annotation() returns the policy it wraps unchanged, so marking a process is never a separate decision. The annotation follows every process Bazel starts, including the Bazel server, which the client launches as a double-forked daemon. Santa passes annotations on to the child when a process forks, so the server keeps the mark after it leaves the client’s process tree, and so does everything the server runs. A fallback rule, which runs only when no other rule matches a binary, can then allow anything that isn’t part of macOS and has Bazel behind it:
// Fallback rule
!target.is_platform_binary && has_annotation("bazel") ? ALLOWLIST : UNSPECIFIED
With that pair, a developer can bazel build, bazel test and bazel run their project in Lockdown mode. Neither rule names a compiler, a linker or anything else in the toolchain, so they keep working when the project changes its toolchain.
The cost is negligible. Santa passes the mark on as it records each fork and exec, and has_annotation() is a hash lookup, not a walk up the process tree.
Both sides can be scoped with anything in the CEL context. The rule on Bazel can annotate only the builds of certain projects, and the fallback rule can add conditions of its own, such as never allowing a build output to run as root:
// Rule on bazel: only annotate builds started in the acme checkout
cwd.startsWith("/Users/alice/src/acme/") ? add_annotation("bazel", ALLOWLIST) : ALLOWLIST
// Fallback rule: never as root
!target.is_platform_binary && euid != 0 && has_annotation("bazel") ? ALLOWLIST : UNSPECIFIED
Trace AI Agent Activity
A name can carry a {session} placeholder, which Santa replaces with the PID and PID version of that execution. One rule can then give each run of a tool, and everything that run starts, a name of its own. has_annotation() matches names exactly, so the rule adds the plain name too, for later rules to test:
// If Claude Code runs as PID 4521 with PID version 18734, it and everything it
// starts get both claude-code-4521-18734 and claude-code.
add_annotation(['claude-code-{session}', 'claude-code'], ALLOWLIST)
Execution events in Workshop list the annotations on the process that ran, on the event details page and as a filter on the events table, and Workshop’s macOS telemetry schema carries them on each process record.
Use Cases
- Run Lockdown on developer Macs. Annotate the build system once, and let a fallback rule allow what it builds and runs, without knowing the toolchain.
- Group an AI agent’s work by run. Give each Claude Code session its own annotation and filter Workshop’s execution events by it.
- Check once, decide many times. Let rules on
curl,sshorgittesthas_annotation('claude-code')instead of each repeating the same ancestor walk.
More to Come
Next up is annotation_exists(). has_annotation() asks whether the process being executed carries a name. annotation_exists() asks whether any process on the Mac carries it right now, so a rule can make one tool’s policy depend on another tool that’s running somewhere else on the Mac:
// Allow this tool only while a Codex session is running
annotation_exists('codex') ? ALLOWLIST : BLOCKLIST
DNS Rules
Network rules match connections. 2026.9 adds DNS rules, which act one step earlier: they match the name a Mac looks up, before it resolves, and apply to the whole Mac rather than one process.
How It Works
A rule lists hostnames, which match exactly, and domains, which also match every name under them. A block rule answers the lookup itself with NXDOMAIN or NODATA, an audit rule lets it through and reports it to Workshop, and the names Santa needs to reach Workshop always resolve. Santa enforces DNS rules through its network extension.
Use Cases
- Block a domain, not an application. One rule covers a domain and every name under it.
- Audit before you block. See which applications look a domain up before you block it.
- Carve out an exception. Block a domain and allow the one hostname under it that people still need.
More in Santa 2026.9
Security Key Approvals
A CEL rule that holds an execution for the user could already ask for Touch ID. 2026.9 adds REQUIRE_SECURITY_KEY, a touch on a FIDO2 security key attached to the Mac, and REQUIRE_PRESENCE, which accepts either. Standalone mode accepts a key too, so a user can approve on a Mac with no Touch ID. A key proves that a person was at the Mac, not who they are: any key will do. The user authorization documentation covers the cooldown helpers and what each value accepts.
Executable Integrity
Santa evaluates the file on disk when a process launches. If that file changes during the launch, or Santa can’t read it, the file Santa checked may not be the one the kernel loaded. The new ExecutableIntegrityPolicy setting decides what happens then. Under the default, Enforce, Santa denies the execution in Lockdown and Standalone modes. Report and Ignore evaluate rules against the file on disk, and Report always uploads the event. Monitor mode treats Enforce as Report. Workshop sets the policy per tag and shows the value each host reports.
Check your fleet before you upgrade. Enforce denies every binary Santa can’t read, including short-lived build outputs and binaries on unreliable network or removable volumes. Set Report on the tags that cover those Macs.
Freshly Built Binaries
Commands like go run, cargo run and bazel run execute a binary right after the compiler writes it, often before Santa has created its transitive rule. With transitive rules enabled, Santa 2026.9 holds such an execution until the rule is created, for up to CompilerTransitiveWaitMilliseconds (2 seconds by default), and kills it if no rule allows the binary in time.
Parent Directory Protection
Renaming or cloning a directory also moves or clones every path beneath it. File access rules have a new ParentDirectoryProtection option for those operations on the directories above a rule’s paths. audit, the default, logs them without blocking. enforce evaluates them as if they touched the rule’s paths directly, so the rule’s audit-only setting still decides whether they’re blocked. disabled ignores them. Workshop sets the option per rule.
Removable Media Messages
Workshop can now set, per tag, the messages Santa 2026.9 shows when it blocks or remounts removable media.
More in Workshop 2026.9
Your Own Slack Approval Message
The Slack message Workshop sends when Santa blocks software is now yours to write: the text, each button’s label, inline app details, and emoji. A live preview shows what each person sees, because the requester and the approver get different buttons.
Host Rules Follow the User
When a Mac registers for the first time, Workshop copies the host rules from its primary user’s most recent Mac of the same OS. Rules from approvals and hand-written host rules survive a hardware refresh, so nobody has to approve their tools a second time.
More AI Providers
AI chat can now use OpenRouter and any number of named OpenAI-compatible endpoints, alongside Anthropic, OpenAI and Google. Several providers can stay connected at once, and the model picker groups models by provider.
Santa Version Tracking
Fleet Metrics adds a graph of the Santa versions across your fleet over 7, 30 or 90 days, by tag, and the outdated hosts card now shows a percentage.
You may also like
Announcing Santa and Workshop 2026.8
Santa and Workshop 2026.8 add time based rules, a top-level Tags section, file access process overrides, sequence signals, and Nix package rules
Announcing Santa and Workshop 2026.7
Santa and Workshop 2026.7 add rule packs for every rule type, richer Signals, package inventory scanning, redesigned Commands, and more
Announcing Santa & Workshop 2026.6
Santa and Workshop 2026.6 add network rules, privilege management, Signals, webhooks, a redesigned Ready for Lockdown report, and more