Skip to main content

Overview

Use this guide to install Beacon on managed Macs and forward Claude Code runtime and inventory telemetry to Google Cloud Storage without asking users to configure the endpoint. The deployed state is:
  • Beacon and Vector are installed under /opt/beacon.
  • com.beacon.endpoint.collector runs the system endpoint.
  • Claude Code hooks are installed for the logged-in console user.
  • Runtime and inventory events are written to /var/log/beacon-agent/runtime.jsonl and /var/log/beacon-agent/inventory_state.jsonl.
  • com.beacon.endpoint.gcs-forwarder uploads both streams under one root prefix:
Use a root prefix such as beacon-prod, not beacon-prod/runtime or beacon-prod/inventory. The installer normalizes those older suffixes, but new deployments should use the root layout.

1. Prepare Google Cloud

Set placeholders in an administrator shell:
Create the bucket and writer service account:
roles/storage.objectCreator can create objects but cannot list, read, overwrite, or delete them. A successful writer therefore cannot validate delivery by running gcloud storage ls or cat. Create a separate read-only identity for validation and downstream consumers:
Apply lifecycle, retention, logging, and CMEK controls in Google Cloud according to your organization’s policy.

2. Deliver the writer credential

Vector 0.56 supports a service-account JSON file through GOOGLE_APPLICATION_CREDENTIALS and GCE metadata credentials. Managed Macs do not normally have GCE metadata, and interactive gcloud auth application-default login credentials or Workload Identity Federation are not a reliable launchd authentication contract for this Vector version. Create a key only when your organization permits service-account keys:
Deliver that file with Jamf’s managed-file or secret-delivery mechanism to a root-owned location outside Beacon’s managed tree, for example:
Do not upload the JSON as an ordinary Jamf script parameter, print it in policy logs, commit it, or place it below /opt/beacon or /Library/Application Support/Beacon. Beacon upgrades, repair, and cleanup own those trees. On the Mac, enforce restrictive permissions:
The packaged helper stores only the credential path in /Library/Application Support/Beacon/Forwarders/gcs-vector.env; the JSON stays in the externally managed location.

3. Configure the Jamf policy

Upload the signed Beacon endpoint package, which includes:
Use one policy to install the package and a second policy to deliver the credential and configure forwarding. Add this Jamf script to the second policy:
Configure the Jamf parameter labels: The helper writes:
Runtime starts at end to avoid an unexpected historical upload. Inventory starts at beginning so an initial snapshot created before Vector starts is not missed.

4. Validate a managed Mac

Check services, files, and the non-secret configuration:
Generate runtime and inventory events:
Allow up to five minutes for the default Vector batch timeout. Validate with the separate reader identity, not the write-only endpoint credential:
The administrator running impersonation also needs roles/iam.serviceAccountTokenCreator on the reader account. Alternatively, validate with your existing security operations reader identity. Grant that role to a designated validator:

Credential rotation

Create and deliver a new key before deleting the old one:
After securely transferring the new file to the Mac, replace the externally managed JSON atomically, preserve root:wheel and mode 0600, then restart the forwarder:
After new objects arrive, list keys and delete the retired key:

Troubleshooting

Check launchd and Vector stderr:
Common failures:
  • GOOGLE_APPLICATION_CREDENTIALS is missing or unreadable: confirm the path in gcs-vector.env, the external file, and root read permission.
  • 403 Forbidden: confirm the credential belongs to the expected service account and that account has roles/storage.objectCreator on the target bucket. Confirm any CMEK key also permits encryption.
  • Uploads succeed but gcloud storage ls fails under the writer: expected; objectCreator cannot inspect objects. Use the reader identity.
  • No recent runtime objects: runtime starts at end; write a validation event after the forwarder is running.
  • No inventory objects: force an inventory heartbeat and inspect /var/log/beacon-agent/inventory_state.jsonl.
For idempotent repair using the saved settings: