macOS Kernel & System Extensions · Lesson 7

Endpoint Security & eslogger

The family behind every Mac EDR tool — and a built-in command that lets you watch the kernel narrate process launches in real time.

🎯
By the end you'll understand how Endpoint Security observes (and can block) system events, why building an ES client needs Apple's blessing — and you'll stream live exec events on your Mac with Apple's pre-entitled eslogger, no entitlement required.

Your content filter from Lessons 2–6 watches network flows. Endpoint Security (ES) watches system events — every process that launches, file that opens, mount, signal, fork. It's how Mac Monitor (already running on your Mac) and tools like CrowdStrike, SentinelOne, and Jamf Protect see what's happening.

1The model: subscribe, observe, (maybe) decide

ES is a C API. You create a client, subscribe to event types, and a handler fires for each event. Two flavours of event:

KindWhat you can doExample
NOTIFYObserve only — the event already happened."process /usr/bin/curl launched" → log it.
AUTHGate it — the kernel blocks until you return ALLOW or DENY."about to exec this binary" → deny if it's malware.

That AUTH power — synchronously vetoing an exec or open — is exactly what KAUTH kexts used to do in the kernel. ES moved it to a sandboxed user-space process. The skeleton in C:

es_client_t *client; es_new_client(&client, ^(es_client_t *c, const es_message_t *msg) { if (msg->event_type == ES_EVENT_TYPE_NOTIFY_EXEC) log_path(msg->event.exec.target); // observe if (msg->event_type == ES_EVENT_TYPE_AUTH_EXEC) es_respond_auth_result(c, msg, is_evil(msg) ? ES_AUTH_RESULT_DENY : ES_AUTH_RESULT_ALLOW, false); }); es_event_type_t events[] = { ES_EVENT_TYPE_NOTIFY_EXEC }; es_subscribe(client, events, 1);
Why you can't just build & run this

ES requires com.apple.developer.endpoint-security.client — a restricted entitlement granted only via Apple's System Extensions request form (they vet your company/use-case). Unlike the Network Extension capability you self-served in Lesson 5, there's no portal toggle. Plus the client needs Full Disk Access. This is the wall we flagged in Lesson 1.

2The flow, visually

a processexec /usr/bin/curl kernel · ES subsystemholds the syscall (AUTH) your ES clientuser space · sandboxed proceedor blocked message ALLOW/DENY
For AUTH events the kernel waits for your verdict — so a slow or crashed ES client can freeze the machine. ES caps response time to keep the system safe.

3Do this now — watch ES live with eslogger

You can't ship an ES client without Apple's nod, but macOS includes eslogger — Apple's own, fully-entitled ES client. It's the safe way to see ES. Give Terminal Full Disk Access (System Settings ▸ Privacy & Security), then:

▶ run me$ sudo eslogger exec # Ctrl-C to stop. try: open -a Calculator

Every process launch on your Mac streams as JSON. One event, trimmed, looks like this:

{ "event": { "exec": { "target": { "executable": { "path": "/System/Applications/Calculator.app/Contents/MacOS/Calculator" }, "signing_id": "com.apple.calculator", "team_id": null, "is_platform_binary": true } } }, "process": { "executable": { "path": "/usr/libexec/runningboardd" }, "ppid": 1 }, "event_type": 9, "action_type": "notify", "schema_version": 1 }
✓ You're seeing the same firehose EDRs see

This is real Endpoint Security data — the exact event stream Mac Monitor consumes. Try sudo eslogger open (file opens) or sudo eslogger es_event_types to list everything subscribable. No code, no entitlement — just observe.

4A taste of the event taxonomy

CategoryExample event types
Processexec, fork, exit, signal, get_task (code injection!)
Fileopen, create, unlink, rename, write, clone
Mount / diskmount, unmount, remount
Systemsetuid, kextload, iokit_open, cs_invalidated (code-sign tampering)

There are 100+ event types. An EDR subscribes to a curated set, builds a process tree, and flags anomalies — all from this stream.

5ES vs. your content filter

Network Extension (you built)Endpoint Security
Watchesnetwork flowsprocess/file/system events
LanguageSwift / Obj-CC API (call from C/Obj-C/Swift)
Entitlementself-service capabilityApple request form
Replacedsocket-filter kextsKAUTH kexts
Can block?yes (.drop())yes (AUTH DENY)

6Flashcards

NOTIFY vs AUTH events?

NOTIFY = observe after the fact. AUTH = the kernel blocks pending your ES_AUTH_RESULT_ALLOW/DENY — you can veto the action.

Why can't you just build and run an ES client like you did the content filter?

ES needs com.apple.developer.endpoint-security.client, granted only via Apple's request form (they vet you), plus Full Disk Access. The NE capability was self-service; ES is not.

How can you watch real ES events with zero entitlement?

sudo eslogger <event> — Apple's built-in, pre-entitled ES client (e.g. sudo eslogger exec). Needs Full Disk Access for Terminal.

What legacy kext mechanism did ES replace?

KAUTH (kernel authorization) kexts — and the older in-kernel MAC hooks.

💬 Ask your teacher. Want to build a process tree from eslogger output, see what events Mac Monitor subscribes to, or understand the AUTH-deadline risk? Ask. One family left — the drivers: say "Lesson 8".