Skip to content

Endpoint agent install

By the end of this guide you will have a Puck agent running on a macOS or Linux host, heartbeating to your brain, and visible in the Fleet page of the console.

Before you start

RequirementDetails
OS / architecturemacOS arm64 or amd64, Linux amd64. Windows is not yet supported.
Outbound networkThe host needs outbound HTTPS (TCP 443) to your brain URL. No inbound ports are required.
Install permissionsYou need to be able to write to /usr/local/bin (or another directory on $PATH) and create a config file. MDM / JAMF managed Macs: deploy via a script policy — the agent has no kernel extension or kext requirement.
Brain API keyGenerate one in Settings → API keys in the console. Copy it before starting — it is only shown once.

Steps

1. Download the binary

Choose the build that matches your host:

Terminal window
# macOS Apple Silicon
curl -fsSL https://releases.puck.security/latest/puck-darwin-arm64 -o /tmp/puck
# macOS Intel
curl -fsSL https://releases.puck.security/latest/puck-darwin-amd64 -o /tmp/puck
# Linux x86-64
curl -fsSL https://releases.puck.security/latest/puck-linux-amd64 -o /tmp/puck

2. Verify the checksum

Terminal window
curl -fsSL https://releases.puck.security/latest/puck-checksums.txt -o /tmp/puck-checksums.txt
grep "$(uname -m)" /tmp/puck-checksums.txt | sha256sum --check

The output should say puck: OK. Do not proceed if the checksum fails.

3. Install the binary

Terminal window
chmod +x /tmp/puck
sudo mv /tmp/puck /usr/local/bin/puck

4. Write the config file

Create /etc/puck/config.json (or ~/.puck/config.json for a user-scoped install):

{
"brain_url": "https://brain.your-org.example",
"api_key": "pck_live_…",
"log_level": "info"
}

Config fields (all correspond to Config struct in the agent):

FieldEnv var overrideDescription
brain_urlPUCK_BRAIN_URLHTTPS URL of your brain. No trailing slash.
api_keyPUCK_API_KEYAccount API key from the console.
agent_idPUCK_AGENT_IDStable identifier for this host. Defaults to puck-<hostname>.
cache_dirPUCK_CACHE_DIRLocal cache directory. Defaults to ~/.puck.
log_levelPUCK_LOG_LEVELdebug, info, warn, or error. Default info.
verify_key_pathPUCK_VERIFY_KEY_PATHPath to the brain’s Ed25519 public key for plan-signature verification. Leave blank to skip pinning (not recommended in production).
ca_cert_pathPUCK_CA_CERT_PATHPath to a custom CA cert for mTLS (optional).
client_cert_pathPUCK_CLIENT_CERT_PATHPath to the agent’s client certificate for mTLS (optional).
client_key_pathPUCK_CLIENT_KEY_PATHPath to the agent’s client private key for mTLS (optional).

Tags link this agent to tag policies that control its behavior — allowed commands, severity floors, investigation prompts. Pass them as a comma-separated string:

Terminal window
puck --tags endpoint,team-engineering,mac-fleet

Or add them to the config file:

{
"brain_url": "https://brain.your-org.example",
"api_key": "pck_live_…",
"tags": ["endpoint", "team-engineering", "mac-fleet"]
}

6. Run the agent

Terminal window
# Foreground (for testing)
puck --config /etc/puck/config.json
# As a launchd service on macOS
sudo launchctl bootstrap system /Library/LaunchDaemons/com.puck.agent.plist
# As a systemd service on Linux
sudo systemctl enable --now puck

Example launchd plist (/Library/LaunchDaemons/com.puck.agent.plist):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key> <string>com.puck.agent</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/puck</string>
<string>--config</string>
<string>/etc/puck/config.json</string>
</array>
<key>RunAtLoad</key> <true/>
<key>KeepAlive</key> <true/>
<key>StandardOutPath</key> <string>/var/log/puck.log</string>
<key>StandardErrorPath</key><string>/var/log/puck.log</string>
</dict>
</plist>

Example systemd unit (/etc/systemd/system/puck.service):

[Unit]
Description=Puck endpoint agent
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/puck --config /etc/puck/config.json
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target

mTLS (optional)

Puck supports mutual TLS for environments that require it. To enable:

  1. Obtain a client certificate and key for this agent from your PKI.
  2. Set ca_cert_path, client_cert_path, and client_key_path in the config.
  3. Set verify_key_path to the brain’s Ed25519 public key to pin plan signatures.

Without mTLS the agent communicates over standard TLS (the brain cert is validated normally) and plans are verified by API key. mTLS adds a second layer: the brain rejects connections from agents whose client cert is not signed by your CA.

Verify it worked

Within 60 seconds of starting the agent, open the console and navigate to Fleet. The new host should appear with:

  • Status: Connected
  • OS and architecture populated
  • Last heartbeat within the last minute
  • Any tags you supplied at startup

You can also poll the API directly:

Terminal window
curl https://brain.your-org.example/api/v1/agents \
-H "Authorization: Bearer pck_live_…" \
| jq '.[] | select(.agent_id == "puck-<hostname>")'

If the agent does not appear within 2 minutes, check the agent log (/var/log/puck.log or journalctl -u puck) for connection errors or authentication failures.

Next steps

  • Cloud agent — deploy Puck inside an AWS, GCP, or Kubernetes environment to investigate cloud control planes
  • Quickstart — run your first investigation across the fleet