Skip to main content

Overview

Use this guide to deploy Beacon to Apple Silicon Macs with Rippling Device Management, configure Claude Code telemetry for the logged-in user, and forward runtime and inventory events to Google Cloud Storage (GCS). The deployed state is:
  • Rippling assigns the signed Beacon package to a Supergroup.
  • Beacon and Vector are installed under /opt/beacon.
  • com.beacon.endpoint.collector receives local Claude Code telemetry.
  • Claude Code hooks are installed for the active console user.
  • Runtime and inventory events are written to:
    • /var/log/beacon-agent/runtime.jsonl
    • /var/log/beacon-agent/inventory_state.jsonl
  • com.beacon.endpoint.gcs-forwarder uploads both streams:
Use a root prefix such as beacon-prod, not beacon-prod/runtime or beacon-prod/inventory.

Prerequisites

Prepare:
  • Rippling IT with Device Management.
  • Target Macs enrolled in Rippling MDM and connected through the Rippling Agent.
  • A pilot Supergroup scoped to assigned Apple Silicon Macs and the intended Claude Code users.
  • A signed and notarized BeaconEndpointAgent-<version>-arm64.pkg that includes /opt/beacon/bin/vector.
  • A GCS bucket and permission to manage its IAM policy.
  • A policy decision that permits a service-account key on managed endpoints.
  • A separate GCS reader identity for delivery validation.
Rippling’s public documentation does not establish a protected arbitrary-file delivery feature or ordering dependencies between custom installers and scripts. Confirm available secret/file controls in your tenant. The flow below uses recurring reconciliation so devices converge after each prerequisite arrives.

1. Prepare Google Cloud

Set administrator-shell placeholders:
Enable APIs and create the bucket:
Create the endpoint writer:
roles/storage.objectCreator permits new object creation but not listing, reading, overwriting, or deleting objects. This limits the endpoint credential, but it also means that credential cannot validate uploads. Create a separate read-only identity:
Apply lifecycle, retention, access logging, and CMEK controls according to your organization’s Google Cloud policy.

2. Create and deliver the writer credential

The packaged Vector version supports a service-account JSON file through GOOGLE_APPLICATION_CREDENTIALS and GCE metadata credentials. A managed Mac does not normally have GCE metadata. Interactive Application Default Credentials and Workload Identity Federation are not a reliable authentication contract for this launchd service. Create a key only when service-account keys are permitted:
Use this endpoint path, replacing the organization name:
Deliver the JSON using one of these methods, in preference order:
  1. A protected arbitrary-file or secret-delivery capability enabled in your Rippling tenant.
  2. A separate, tightly scoped signed custom installer package that writes only this credential file with root:wheel ownership and mode 0600.
Keep credential deployment separate from the Beacon package so the key can be rotated or revoked without rebuilding Beacon. Restrict access to the credential installer and its source artifact. Do not:
  • paste the JSON into a Rippling custom Bash script;
  • print it in script output or activity logs;
  • place it under /opt/beacon or /Library/Application Support/Beacon, which Beacon owns;
  • deploy it with group or world read permission.
Validate the delivered file on a pilot Mac:
The Beacon helper stores only this path in its root-readable Vector environment file. The credential remains in the externally managed location.

3. Upload the Beacon custom installer

In the Rippling Devices app:
  1. Upload the signed Beacon .pkg as a custom installer.
  2. Configure it as system-level software.
  3. Assign it to the pilot Supergroup.
  4. Wait for installation on the next device connection.
  5. Review software installation status, pending actions, and activity logs.
Verify the installed payload:
The package postinstall creates and starts the base collector. The GCS reconciliation script in the next section configures the forwarder and repairs Claude Code hooks.

4. Deploy the Rippling reconciliation script

Create a macOS custom Bash script in Rippling and assign it to the same pilot Supergroup. Configure it on a recurring schedule during rollout because:
  • Rippling’s public documentation does not define custom installer dependency ordering;
  • the credential may arrive separately;
  • Claude Code hooks require a logged-in non-root console user.
Use this script, replacing the four configuration values:
These are non-secret configuration values: Do not add the credential JSON itself to the script. The helper’s smoke test prints recent runtime and inventory events. The wrapper truncates a mode-0600 log under root’s private home and redirects verbose output there so retained prompts, tool inputs, or command output are not exported through Rippling’s script-output view.
The packaged helpers remain under /opt/beacon/jamf for compatibility, but this flow does not call Jamf APIs. Environment variables are used instead of Jamf positional parameters.

What the helper does

The combined helper:
  • verifies the GCS bucket, Vector binary, and credential path;
  • requires the credential to be root-owned with mode 0400 or 0600;
  • writes and validates the Vector configuration;
  • creates:
  • starts com.beacon.endpoint.gcs-forwarder;
  • repairs com.beacon.endpoint.collector;
  • prepares the runtime and inventory JSONL files;
  • grants the active console user append access;
  • installs Claude Code hooks for the active user;
  • runs a local hook smoke test and validates endpoint status.
Runtime forwarding starts at end. Inventory starts at beginning so the initial inventory snapshot is not missed. If no interactive user is logged in, forwarder and endpoint reconciliation can complete before the hook-repair phase returns non-zero. Keep the recurring script assigned so a later user session completes hook installation.

5. Validate a pilot Mac

Rippling state

In Rippling, confirm:
  • the device is assigned and remains in the pilot Supergroup;
  • MDM and Rippling Agent status are healthy;
  • the Beacon custom installer succeeded;
  • the credential delivery action succeeded;
  • no relevant pending action remains;
  • the recurring script’s latest output completed after an interactive login.

Local endpoint and services

Check local files and non-secret forwarder settings:

Generate validation events

Generate a runtime event and a forced inventory heartbeat after the forwarder is running:
Allow up to five minutes for Vector’s default batch timeout.

Validate GCS with the reader

Use the separate reader identity, not the endpoint writer:
The administrator performing impersonation needs roles/iam.serviceAccountTokenCreator on the reader service account:
Inspect a validation object:
Fully restart Claude Code, start a new session, and perform a small tool action. Confirm a newer runtime object arrives.

6. Expand the rollout

After the pilot is healthy:
  1. Expand the custom installer, credential delivery, and reconciliation script to a staged production Supergroup.
  2. Keep all three assignments scoped identically.
  3. Continue recurring reconciliation for newly assigned devices and user logins.
  4. Review Rippling software status, pending actions, script output, and activity logs during each stage.
  5. Validate GCS object freshness with the reader identity or your downstream security pipeline.

Credential rotation

Create the replacement key before deleting the old one:
Update the protected file or credential installer while preserving the same absolute path, root:wheel ownership, and mode 0600. The recurring reconciliation script restarts the forwarder when it next runs. To restart immediately:
After new objects arrive, identify and delete the retired key:

Package updates

Upload the newer signed Beacon package to Rippling and test it with the pilot Supergroup. Package postinstall restarts the collector and restores an existing GCS forwarder. Keep the reconciliation script assigned to repair hooks and forwarding state after the update. Rippling’s public documentation does not define custom-installer supersedence or version comparison behavior. Verify your chosen update pattern in the pilot before replacing the production assignment.

Uninstall

Use an explicit cleanup sequence:
  1. Remove the Mac from the recurring reconciliation script.
  2. Copy the cleanup helper to a temporary root-only path while /opt/beacon still exists.
  3. Remove or unassign the Beacon custom installer so Rippling does not reinstall it after cleanup.
  4. Run the copied helper as a one-time root script and review all warnings.
  5. Verify Beacon LaunchDaemons, files, and the package receipt are gone.
  6. Remove the separately managed writer credential.
  7. Revoke the writer key.
The cleanup helper is best-effort and exits successfully after some warning conditions, so the explicit checks are required. It does not remove the externally managed credential path. Do not rely only on automatic removal when a device leaves the Supergroup: Rippling’s public documentation does not confirm that custom installer removal runs Beacon’s cleanup helper.

Troubleshooting

Review Rippling script output. Confirm it ran as root and that the Beacon package, Vector binary, helper script, and credential file all exist. A recurring run may occur before the custom installers have completed.
The helper intentionally returns non-zero because Claude Code hooks are per-user. Keep the recurring script assigned and rerun it after the employee logs in. Forwarder and collector setup may already be healthy.
Check path, ownership, and mode:
The path must be absolute, the owner must be root, and the mode must be 0400 or 0600.
Inspect launchd and Vector errors, then validate the saved configuration without starting a second Vector process:
Confirm the JSON belongs to the expected writer service account and that the account has roles/storage.objectCreator on the target bucket. If the bucket uses CMEK, confirm the writer can use the encryption key.
This is expected. roles/storage.objectCreator cannot list or read objects. Validate with the reader identity.
Runtime forwarding starts at end. Generate beacon endpoint gcs validate --system after the forwarder is running, wait up to five minutes, and inspect Vector stderr.
Force an inventory heartbeat, inspect /var/log/beacon-agent/inventory_state.jsonl, and confirm the Vector config includes the inventory source and /inventory/date=%F/ key prefix.

Rippling references

Rippling MDM overview

Review package deployment, Supergroups, recurring scripts, updates, and uninstall.

Claude Code

Review the Claude Code telemetry surface and local configuration.

GCS command reference

Review local GCS validation commands and generated forwarding assets.

Endpoint operations

Review system paths, services, permissions, update behavior, and cleanup.