/var/log/beacon-agent/runtime.jsonl and ships Vector at /opt/beacon/bin/vector.
What you’ll set up
When you finish, each Mac in the pilot has:- Beacon installed under
/opt/beacon, with its collector running as the LaunchDaemoncom.beacon.endpoint.collector. - Claude Code, Codex CLI, and Cursor reporting to that collector for the user who is logged in at the Mac.
- Agent activity written to
/var/log/beacon-agent/runtime.jsonl. - A forwarder (Vector, shipped in the package) posting each new line to the Azure Monitor Logs Ingestion API.
BeaconRuntime_CL, which is the table Sentinel hunts over. Azure Monitor Agent does not run on macOS, so this guide uses Vector. Linux hosts can use Azure Monitor Agent and still fill the same table. See Microsoft Sentinel forwarding.
Before you start
The Macs do not need Beacon installed beforehand. Jamf installs it in Policy 1.
Claude Desktop chat is not part of this rollout. Beacon does not collect that app. Claude Code is the
claude CLI and the Claude Code extension. Codex is the Codex CLI. Cursor is the Cursor app.1. Look at Beacon on one Mac (optional)
A Homebrew install lets you see what a session looks like before Jamf is involved. It stays on that Mac:beacon endpoint status and beacon endpoint doctor. A fresh install reports one warning, harness_observed, until an agent actually runs. Start a new Claude Code or Codex session and the events are in ~/.beacon/endpoint/logs/runtime.jsonl.
Leave this Mac as it is. The pilot Macs get the package in Policy 1, and they forward a different log.
2. Prepare Sentinel
Do this once, in Azure. The same workspace then receives every pilot Mac. On the Mac from step 1, generate the content pack with the system log path filled in.--system is what makes vector.toml tail /var/log/beacon-agent/runtime.jsonl:
vector.toml, the KQL transform, starter hunting queries, and a sample event. Full portal steps are in Microsoft Sentinel forwarding. For these Macs, finish these four things:
- Create the custom table. Name it
BeaconRuntime. Azure adds_CL, so the table you query isBeaconRuntime_CL. Uploadsample-event.jsonland pastedcr-transform.kqlin the schema step. - Create a Data Collection Endpoint in the same region as the workspace. Copy its logs ingestion URL. It looks like
https://<dce>.<region>.ingest.monitor.azure.com. - Deploy
dcr-logs-ingestion-template.jsonwith the workspace resource ID and the Data Collection Endpoint resource ID. Copy the rule’simmutableId. It starts withdcr-. - Register an app in Microsoft Entra ID, create a client secret, and grant that app the Monitoring Metrics Publisher role on the Data Collection Rule. Role assignment can take several minutes.
login.microsoftonline.com and to the Data Collection Endpoint hostname. Nothing else.
Beacon never stores the tenant ID, client secret, workspace ID, or ingestion URL. Those stay in the forwarder’s environment file on the Mac, written by Policy 2.
3. Set up Jamf
Create four policies, in this order, scoped to the pilot Smart Group. A person has to be logged in at the Mac for policies 3 and 4. At the login window those two exit with an error, which is expected.Policy 1: install the package
Download the signed package for the release you are piloting. The asset name isBeaconEndpointAgent-<version>-arm64.pkg, attached to the GitHub release with a .sha256. Check the checksum before uploading it to Jamf.
In Jamf Pro, upload the package and add it to a policy named Beacon - Install Package with the install action. The package installs:
Policy 2: forward to Sentinel
Add a script namedBeacon - Configure Sentinel Forwarding. It writes Vector’s config, a root-owned environment file, a small wrapper, and a LaunchDaemon, then starts it.
Jamf script parameters:
Deliver the secret with Jamf’s own secret mechanism if you have one. A script parameter is visible to Jamf administrators.
sentinel-vector.env, mode 0600, owned by root. It is not in Beacon’s config.json.
Policy 3: Claude Code and Codex
Add a script that runs the helper shipped in the package:/var/log/beacon-agent/runtime.jsonl.
Codex sends prompts, tools, and token usage over OTLP to 127.0.0.1:4317. Its SessionStart hook adds the OS user, which the OTLP spans do not carry. Claude Code sends prompts, tools, approvals, and token usage over the same OTLP endpoint. Its hooks add session start and end, file activity, command output, and subagent lifecycle, which Claude Code’s OTLP export does not carry.
After the policy, that person quits Claude Code and Codex completely, reopens them, and starts a new session. A session that was already open keeps the old settings.
Policy 4: Cursor
Add a script that runs the other helper shipped in the package:What each harness sends
Events from these three are rows in the same table. Filter with
HarnessName.
Other local agents are installed the same way, one policy per harness, with beacon endpoint hooks install or that runtime’s own setup. The runtime list is the catalog. This pilot does not turn on Claude Cowork. Cowork is an org-admin OTLP export, documented on Claude Cowork, and it is a different harness name (claude_cowork).
4. Check one Mac
On a pilot Mac, after all four policies and a new session in each agent:Service: loaded=true running=true means the collector is up. Run the two hooks checks as the person who is logged in. They read that person’s home, the same place Policies 3 and 4 wrote: Claude Code should say hooks are installed at that person’s ~/.claude/settings.json, and Cursor at that person’s ~/.cursor/hooks.json. The forwarder print should show state = running.
Write a known event after the forwarder is running, so Vector is already watching the end of the file:
/Library/Logs/Beacon/com.beacon.endpoint.sentinel-forwarder.err on the Mac. An authentication error there is the Entra app or the Monitoring Metrics Publisher role. A path error means Vector is not reading /var/log/beacon-agent/runtime.jsonl. Rows in the local file with no matching rows in the table mean the forwarder started before those lines were written: Vector only ships lines appended after it starts.
Related
Microsoft Sentinel forwarding
Table setup, both ingestion paths, and the content pack.
macOS
Package install, launchd, and the system log path.
Jamf
Package deployment, Extension Attributes, and validation.
Anthropic, OpenAI, and Cursor
The same three harnesses, forwarding to S3 instead of Sentinel.