What you’ll set up
Beacon on each Mac records agent activity and uploads it to your bucket with a key that can only create objects. For each new object, the bucket posts a notice to Pub/Sub. Asymptote reads the subscriptions to learn which objects are new, fetches them with its own service account, and loads them into your dashboard. No Asymptote key is involved, and the bucket stays yours and keeps every object. In your Google Cloud project:- A new Cloud Storage bucket just for Beacon, with uniform bucket-level access, public access prevention, and versioning.
beacon-endpoint-writer, a service account your Macs upload with. It can create objects below your Beacon prefix and nothing else.- Read access for Asymptote’s reader,
beacon-clickpipes-reader@asymptote-labs.iam.gserviceaccount.com, on the bucket. - A Pub/Sub topic and two subscriptions, one for agent activity (
runtime) and one for inventory. They let Asymptote load objects in any order, so an upload that arrives late is never skipped.
Asymptote receives the telemetry your Macs upload in full, after Beacon’s local redaction of secrets: prompts, the commands agents ran and their output, tool inputs and outputs, and file paths and diffs.
Before you start
1. Create the bucket and access
Pick a root prefix such asbeacon-prod. Beacon adds runtime/ and inventory/ below it, so don’t put either in the prefix.
- Terraform
- gcloud
Create a Apply it:Review the plan and type
main.tf in a new directory. Change the project, location, bucket name, and prefix:main.tf
yes. It’s working when the apply ends with Apply complete! and prints the outputs. Keep them for step 3. Your own Cloud KMS key, object expiry, and other options are in the base module’s variables.tf.2. Create the writer’s key
Create the key with gcloud, so the private key never enters Terraform state. Use thewriter_email output, or the writer’s email from the gcloud steps:
0600, and then delete your local copy. Wait about a minute before a Mac first uses a brand-new key; Google rejects it for the first few seconds.
3. Send Asymptote the details
Send your Asymptote contact:- the bucket name and prefix;
- the two subscriptions:
asymptote_subscriptions, orprojects/<project-id>/subscriptions/asymptote-<bucket>-runtimeand-inventory.
4. Roll out Beacon to your Macs
Try it on one Mac first, or go straight to your MDM.- One Mac (no MDM)
- Jamf or Rippling
Install Beacon. On an Apple Silicon Mac, in Terminal while logged in at the Mac:The block checks the package against its published SHA-256 and its Apple signature before installing. Start the forwarder with your values from step 1:It’s working when the output shows the forwarder’s
Download, verify, and install
pkgutil should print Status: signed by a developer certificate issued by Apple for distribution. The package sets up Claude Code and Codex for the logged-in user; Try Beacon on One Mac covers what it installs and how to add other agents.Put the writer’s key where the forwarder can use it, in a root-only location outside Beacon’s directories:state = running. When you roll out with an MDM later, this Mac gets the same setup again.5. Confirm it works
On a Mac with Beacon installed, write a test event:Operate
Rotate the writer’s key
Create a new key, deliver it to every Mac, restart the forwarder, confirm a new object arrives, and then delete the old key. Your MDM guide has the exact commands under credential rotation.Remove
- Ask Asymptote to disconnect the bucket.
- Remove the forwarder from your Macs. Uninstalling Beacon removes it.
- Run
terraform destroy. Deleting the writer service account also deletes its keys. Destroy stops at a bucket that still holds objects. To delete the telemetry too, addforce_destroy = trueto thebeacon_gcsmodule, runterraform apply, and then destroy.
Troubleshooting
The forwarder setup fails right after creating the key
The forwarder setup fails right after creating the key
A brand-new service-account key is rejected for the first few seconds (
Invalid JWT Signature). Wait a minute and run the setup again.Objects arrive in the bucket but not in Asymptote
Objects arrive in the bucket but not in Asymptote
Check that the subscriptions exist and that Asymptote’s reader is a subscriber on both:
gcloud pubsub subscriptions get-iam-policy <subscription>. Then send your Asymptote contact the subscription names.The bucket name is already taken
The bucket name is already taken
Someone else, in any project, already has a bucket with that name. Choose another bucket name.
Related
AWS S3
The same setup with an S3 bucket.
Claude with Jamf and GCS
Roll out Beacon with Jamf Pro.
Google Cloud Storage with Terraform
The bucket and writer on their own, without Asymptote reading them.
Hosting options
Compare Managed, Open Source, and Private Deployment.