CClawMetryDocs

Enterprise

Rolling ClawMetry out to a fleet#

This is the one place for fleet install instructions. Other pages link here instead of repeating them. Every path below says what it was tested on, and anything without a tested configuration is marked not tested.

Which release you need

The fleet install command (clawmetry service) and the fleet recipes ship in ClawMetry 0.12.880 and later. Signed self-hosted server images are published from 0.12.878. Check a machine with clawmetry service --help. If that command is unknown, upgrade before you follow the fleet sections.

1. Choose a deployment mode#

The collector always runs on the machine where the agent runs. What you choose is where its data goes.

ModeWhere session data goesCredential neededDetails
Local onlyStays on each machineNoneDeployment modes
Managed cloudEncrypted snapshot to ClawMetry CloudAccount key, per userEncryption
Your own serverYour self-hosted server, in your networkA node token you issueSection 11
No collectorThe runtime's own OpenTelemetry export, straight to your serverA gateway tokenOpenTelemetry ingest

Start local only. It needs no credential and you can connect later without losing history.

2. Tested environments#

Tested means an automated run installed the recipe and checked the result on that runner image. The fleet recipes were run on 15 September 2026 against the merged code that ClawMetry 0.12.880 contains, and the self-hosted checks ran the same day against the published 0.12.880 image. Nothing here was run on a real virtual desktop host.

EnvironmentStatusTested onWhat was checked
Shared Linux host, Ansible recipeTestedGitHub-hosted ubuntu-24.04 runner, the image's system Python (/usr/bin/python3)Two local users, each with a collector running as that user with no login session. Neither user can read the other's data. Uninstall removes the unit.
Windows host, Intune PowerShell scriptTested at registration levelGitHub-hosted windows-2025-vs2026 runner (Windows Server 2025), Python 3.11One logon task for the built-in Users group, least privilege, one instance per session. Desktop users cannot write the shared install. Uninstall removes the task. Two users signed in at once was not observed.
Self-hosted server containerTested on the published 0.12.880 imageubuntu-24.04 (amd64) and ubuntu-24.04-arm (arm64) runnersPulled by digest with no registry credentials. Keyless signature and per-platform SBOM verified. The image contains no Pro plugin. An event survives a container restart. Export refusing a request with no credentials was checked on the branch build only.
Azure Virtual Desktop, multi-sessionNot testedNoneNone
Windows 11 Enterprise multi-sessionNot testedNoneNone
Citrix Virtual Apps and DesktopsNot testedNoneNone
FSLogix profile containers or roaming profilesNot testedNoneNone
Microsoft Configuration Manager (SCCM), Group Policy startup scriptsNot testedNoneThe Intune script is plain PowerShell but was run only as shown above.
Jamf or any macOS fleet toolNo recipeNoneNone
Agents inside WSL or containers on a desktopNot testedNoneNone
Azure Container Apps, AWS ECS, Kubernetes, HelmNot availableNoneNone
Air-gapped installationNot verifiedNoneNone
Reboot and network outage recovery, on either OSNot testedNoneNone

If your environment is marked not tested, we can run a compatibility assessment with you on one agreed profile before any wider rollout. Email enterprise@clawmetry.com. It is an assessment, not a guarantee that the profile is supported.

3. How the fleet collector runs#

One collector per user, running as that user. It reads only that user's agent files and keeps its data in that user's profile. A single privileged service that reads every profile was rejected: it could read every user's content and would attribute all of it to one machine.

LinuxWindows
RegistrationPer-user systemd unit plus logind lingerOne logon task for the built-in Users group
Runs asThe userEach signed-in user, least privilege
After logoffKeeps runningStops with the session. The logon task starts it again at the next sign-in, which was not observed on a real host
Data directory~/.clawmetry, readable only by the user%USERPROFILE%\.clawmetry, profile permissions (not checked by ClawMetry)
UpdatesRe-run the recipe with a new pinRe-run the recipe with a new pin

Check what a machine actually got:

bash
clawmetry service status          # add --json for scripts

It reports whether collection survives logoff and why, whether the data directory is private, and whether automatic updates are on. On Windows it never reports that collection survives logoff.

4. Windows shared hosts and virtual desktop images#

The recipe is deploy/fleet/intune/Install-ClawMetry.ps1 in the ClawMetry repository at v0.12.880. It must run elevated. Intune platform scripts run as SYSTEM, which is enough. It creates C:\Program Files\ClawMetry\venv, installs the package you pin, and registers the all-users logon task.

powershell
powershell.exe -ExecutionPolicy Bypass -NoProfile -File Install-ClawMetry.ps1 -Package "clawmetry==<version>"

Exit code 0 means the task is registered and 1 means it is not, so Intune reports a failed install correctly.

Before you use it on an image:

  • Python must be installed for all users, for example under

C:\Program Files. Every user's collector runs through that interpreter. The script uses python from the path unless you pass -PythonExe, and refuses a Python that lives inside a user profile.

  • A console window may appear at sign-in. The task starts python.exe,

which is a console program, and closing the window stops collection until the next sign-in. This has not been checked on a real multi-session host.

  • The install directory is locked down. The script gives SYSTEM and

Administrators full control and Users read and execute only, so no desktop user can change code that every other user's collector runs.

  • Do not enroll inside the image. The script takes no credential. See

section 7.

  • Cloned images are not guaranteed a fresh machine identity yet, and user

attribution across profile roaming has not been validated.

One machine without Intune#

clawmetry service install --all-users registers the same logon task, but it does not check either precondition the script enforces. It points every user's task at the interpreter you run it from, as-is. Use it only when both of these are true:

  • It runs from a virtual environment created from a machine-wide Python,

for example under C:\Program Files, and never from a Python inside your own profile. Otherwise other users' collectors fail at sign-in and nothing reports it.

  • Only administrators can write that directory. Otherwise any user can

change code that runs as every other user who signs in.

From an elevated prompt, after creating that environment:

powershell
& "$env:ProgramFiles\ClawMetry\venv\Scripts\clawmetry.exe" service install --all-users

If you are not sure both are true, run the script instead.

5. Linux shared and headless hosts#

The recipe is deploy/fleet/ansible/clawmetry.yml. It creates /opt/clawmetry-fleet, installs the pinned package, enables linger for each listed user and registers each user's collector.

bash
ansible-playbook -i inventory deploy/fleet/ansible/clawmetry.yml \
  -e '{"clawmetry_users": ["alice", "bob"]}' -e clawmetry_package=clawmetry==<version>

The shared environment is installed under umask 022 and then forced to root ownership with no group or world write, so no user can change code another user's collector runs. If you install some other way, check this yourself.

One user on a headless server can do the same without Ansible:

bash
clawmetry service install

If the host refuses linger, the command exits 1 and prints the administrator command to run (sudo loginctl enable-linger <user>). It does not claim the collector will outlive logout. That refusal path is covered by unit tests only.

To manage the unit files yourself instead, see Run it as a service.

6. macOS#

There is no macOS fleet recipe, and clawmetry service install --all-users is not supported on macOS. Install per user with the standard installer. A Jamf deployment has not been built or tested.

7. Enroll without putting a secret in the image#

Local-only collection needs no credential at all.

Never put an enrollment key into a golden image, a script file or a world-readable location. Anyone who copies the image or the script copies the key. Neither fleet recipe accepts a key, and the product's tests fail if a key-shaped string appears in them.

To connect, run this as each user at sign-in, from a user-context deployment step that reads the key from your secret store:

bash
clawmetry connect --key "$CLAWMETRY_KEY"

To send data to your own server instead of ClawMetry Cloud, point the node at it first. The key is a node token you issued on that server:

bash
CLAWMETRY_ENDPOINT=https://clawmetry.internal.example.com \
  clawmetry connect --key "$CLAWMETRY_NODE_TOKEN"

Know the limits before you plan around them:

  • The ClawMetry Cloud key is account scoped. Scoped, per-host enrollment

keys are not available yet.

  • Rotate a cloud key by connecting again with the new key. On your own server,

add the new token to the server, reconnect the nodes, then remove the old token.

8. Corporate proxy and custom certificate authority#

The collector uses the operating system's trust store on Python 3.10 and newer, so a corporate root CA your IT team already pushed usually just works. It reads HTTPS_PROXY, HTTP_PROXY and NO_PROXY when the collector starts.

bash
export HTTPS_PROXY=http://proxy.corp.example:8080
export NO_PROXY=localhost,127.0.0.1
export CLAWMETRY_CA_BUNDLE=/etc/ssl/certs/corporate-ca.pem   # only if the trust store lacks it
clawmetry doctor

clawmetry doctor checks DNS, TCP, the proxy, TLS and a heartbeat, and names the certificate authority that is re-signing your traffic. Set these variables where the collector starts, not only in your terminal, then restart it. Full detail: Ports and networking.

9. Local-only and offline operation#

bash
export CLAWMETRY_OFFLINE=1       # no install ping, update check or entitlement probe

Collectors installed by either fleet recipe never update themselves. They detect that the signed-in user cannot write the install and skip automatic updates, so they never exit to retry an upgrade that cannot succeed. A per-user install the user owns keeps automatic updates unless you set CLAWMETRY_AUTO_UPDATE=0. See Upgrades.

An offline or air-gapped installation has not been verified. CLAWMETRY_OFFLINE stops outbound calls from a collector that is already installed; it does not make the install itself work without a package index.

10. OpenTelemetry and SIEM wiring#

  • Send agent activity to your observability backend with OTLP export.

See OpenTelemetry ingest and Exports.

  • Skip the collector for runtimes that export OpenTelemetry themselves, by

pointing them at your own server. See OpenTelemetry ingest.

  • Forward events to a syslog SIEM in CEF or JSON with CLAWMETRY_SIEM_HOST,

CLAWMETRY_SIEM_PORT, CLAWMETRY_SIEM_PROTOCOL and CLAWMETRY_SIEM_FORMAT. This is an Enterprise feature. It has not been tested against a live SIEM receiver for this guide.

11. Run the self-hosted server in your own cloud tenant#

The self-hosted server is one container that receives every node's heartbeats, sessions and events, and serves a fleet page and an audit export. It runs on any Linux host with Docker Compose, including a virtual machine inside your own Azure or AWS account. Detailed per-session views stay on each node.

The image is ghcr.io/vivekchand/clawmetry:<version>, for linux/amd64 and linux/arm64, built from the published package with no Pro plugin inside. Deploy it by digest, and verify it before you run it:

bash
IMAGE=ghcr.io/vivekchand/clawmetry:<version>@sha256:<digest>
cosign verify "$IMAGE" \
  --certificate-identity https://github.com/vivekchand/clawmetry/.github/workflows/container-image.yml@refs/heads/main \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

The release pipeline opens a pull request that pins deploy/self-hosted/docker-compose.yml to a digest, and only after that digest has passed signature, SBOM and restart checks. If the file you have still has a build: block, no verified pin has been merged yet and Compose builds from your checkout.

Steps on a VM in your tenant:

  1. Put the node tokens and the admin user and password in your secret store

(for example Azure Key Vault or AWS Secrets Manager) and write them into .env at deploy time. Never commit them.

  1. docker compose up -d from deploy/self-hosted/.
  2. Terminate TLS in front of port 8900. The container speaks plain HTTP.
  3. Connect each node as shown in section 7.
  4. Back up the volume before every upgrade. To roll back, set the previous

digest and restore the backup.

Only the container on a Docker host was tested, on the runners in section 2. A VM in Azure or AWS was not run, and none of these is available for the self-hosted server today:

  • No Azure Container Apps, AWS ECS, Kubernetes or Helm quickstart.
  • No single sign-on (Entra ID, OIDC or SAML), user directory or roles.
  • No second server instance and no high availability.
  • No automated retention or deletion. Nothing is deleted automatically, so size

the volume for your event volume.

  • No non-root image.

The full runbook, with backup, restore and the SBOM and provenance checks, is docs/self-hosting.md in the ClawMetry repository at v0.12.880. Licensing: Plans and entitlements.

12. Pin, update and roll back#

  • Pin an exact clawmetry==<version> in either recipe.
  • Update by re-running the recipe with the new pin. Windows collectors pick

it up at next sign-in. On Linux, restart each user's clawmetry-sync unit.

  • Roll back by re-running the recipe with the previous pin.
  • Self-hosted server: change the digest, docker compose pull, then

docker compose up -d.

13. Uninstall#

Windows, elevated:

powershell
& "$env:ProgramFiles\ClawMetry\venv\Scripts\clawmetry.exe" service uninstall
Remove-Item -Recurse -Force "$env:ProgramFiles\ClawMetry"

Linux, per user, then once per host:

bash
sudo -u <user> XDG_RUNTIME_DIR=/run/user/<uid> /opt/clawmetry-fleet/bin/clawmetry service uninstall
sudo loginctl disable-linger <user>
sudo rm -rf /opt/clawmetry-fleet

Disconnecting a node stops sync without removing local data. See Uninstall.

14. Resource use#

On the Linux runner, each idle collector used about 137 to 149 MB of memory and a lifetime average of about 2.3 to 2.4% of one CPU over its first 64 seconds, which includes startup. That is a reference point from a CI runner with no agent workload, not a sizing figure for a virtual desktop image. Measure on your own image with a real workload before you size a host pool.

15. Not covered yet#

  • A Windows collector for users who are not signed in.
  • Capped, recoverable buffering through a long network outage, with delivery

receipts.

  • Scoped, rotatable enrollment keys, and a fresh machine identity for pooled

image clones.

  • Per-user attribution validated across logoff and profile roaming on a real

multi-session host.

  • Pause, stop and pre-tool controls verified on a multi-session host.
Cookie preferences