Skip to main content
AI Watch deploys to Linux as a native package (runlayer-aiwatch .deb / .rpm) that installs the aiwatch binary and a cron entry. Every 15 minutes it scans all users on the machine for shadow AI — MCP servers, connectors/plugins, skills, and agents — and reports findings to your Runlayer tenant. An hourly root job applies the AI Watch version selected by your Runlayer tenant.

What you get

Linux is Detect-only:
  • Cron-scheduled shadow-AI scans across all users on the machine (root and service accounts included).
  • Hourly automatic updates to the AI Watch version selected by your Runlayer tenant.
  • No hooks, endpoint modes, Sessions, or browser extension on Linux.
  • In the dashboard, a Linux device shows Detect = Active and Protect / Enforce / Sessions = Disabled. That is the expected state, not an error.

Supported distributions

Standard packages support x86_64 distributions with glibc 2.35 or newer: A running cron daemon is required. The .deb depends on cron | cron-daemon | cronie and the .rpm depends on cronie, so a provider is pulled in automatically on install if missing. Most distros in the “Not supported” column are covered by the legacy build variant below.
Do not install AI Watch inside WSL. Windows AI Watch already scans WSL home directories from the Windows host — a WSL install creates a duplicate device in the dashboard.

Legacy distributions (glibc 2.17)

Each release also ships a legacy build variant built for older x86_64 distributions (glibc 2.17): For a single test device, the one-command installer detects the host’s glibc version and selects this variant automatically. Use the manual commands below for configuration-management installs. Alpine and other musl-based distros remain unsupported by both variants. The legacy artifacts ship as standalone files through the same Runlayer downloads access as the standard bundle — there is no legacy deployment zip; reuse the config templates from the standard bundle:
  • runlayer-aiwatch_<version>_amd64.glibc2.17.deb
  • runlayer-aiwatch-<version>-1.x86_64.glibc2.17.rpm
  • aiwatch-<version>-linux-x86_64-glibc2.17.tar.gz (raw bundle)
  • SHA256SUMS-glibc2.17 — verify with sha256sum -c SHA256SUMS-glibc2.17
Configuration, scanning, and verification are identical to the standard package documented below. Inside the packages the name is still runlayer-aiwatch, so a machine moves between variants with a normal package upgrade; install exactly one variant per machine. Automatic updates never cross variants — only a manual or configuration-management install moves a machine between them (see Updates). The install commands differ, though — these distros predate dnf and local-file apt-get install:
Uninstall likewise: sudo yum remove runlayer-aiwatch on the RHEL family, sudo apt-get remove runlayer-aiwatch on Debian/Ubuntu.
Automatic updates are supported on legacy devices running legacy packages newer than 0.29.9, which stay on the glibc 2.17 variant automatically. Devices on 0.29.9 or earlier need one configuration-management upgrade (Ansible, Salt, or Puppet) to a current legacy package. Future updates are then automatic. See Updates.

Install

Download the aiwatch-<version>-linux-x86_64.zip deployment bundle from your Runlayer downloads access. It contains the .deb, the .rpm, SHA256SUMS, and the config templates. Contact your Runlayer account team if you don’t have the bundle.
1

Verify the artifacts

Verify package integrity with SHA256SUMS:
2

Install the package

The package installs:Nothing executes at install time — the first scan and update check fire on their next cron ticks after you configure the two files below.

Configure

Configuration is two files under /etc/runlayer/aiwatch/. The split matters: per-user scan children run unprivileged and read config.json, so that file is world-readable by design — the org API key must never go in it.

1. /etc/runlayer/aiwatch/config.json (world-readable, non-secret)

Set only Host to your tenant URL. Linux is Detect-only by default, so no Sessions, Enforcement, or discovery flags are needed in the shipped configuration:
Never put the org API key in config.json. The file is world-readable by design so unprivileged per-user scan children can read managed settings. The key belongs in the root-only credentials file below.
Optional keys can be added manually when needed. Settings sync from Runlayer overrides the discovery and scan-tuning keys once a dashboard value is delivered (see How it runs); the config.json values are the fallback until then. Running-process and container discovery are disabled when absent. Container discovery uses the Docker CLI or local Docker Engine API socket (including Portainer-managed hosts without the Docker CLI); on k3s nodes it uses root-only k3s crictl. Other tuning keys share the macOS semantics (see Deploy AI Watch):
DetectContainers needs Docker socket access from the per-user scan children: the cron wrapper drops privileges to each user, so add scanned users to the docker group (or an equivalent socket ACL). k3s container inventory runs only for root’s scan, since k3s crictl requires root.

2. /etc/runlayer/aiwatch/credentials (root-only, 0600)

Set the organization API key — the same rl_org_... key used by your macOS and Windows deployments, minted automatically when the configuration is created in Settings → MDM configuration (copy it from the setup wizard’s deploy step):
Until RUNLAYER_API_KEY is set, both cron wrappers exit quietly without scanning or checking for updates — an unconfigured device produces no errors and no data.

How it runs

/etc/cron.d/runlayer-aiwatch owns two root schedules. Every 15 minutes, /usr/lib/runlayer/run-aiwatch-scan.sh:
  • First refreshes the backend settings snapshot as root (/var/lib/runlayer/aiwatch/backend-config.json, world-readable, root-written), so dashboard-managed discovery and scan-tuning settings reach this run’s scan children. A refresh failure keeps the last-known-good snapshot and never blocks the scans.
  • Enumerates all passwd users with an existing home directory — root and service accounts included; shared home directories are scanned once.
  • Runs aiwatch scan for each user in its own child process with privileges dropped to that user, so one user’s failure never aborts the others.
  • Skips a tick if a scan or update is already running — overlapping runs never queue up.
  • Routes all output to syslog, tagged runlayer-aiwatch (cron never emails root).
At minute 7 of every hour, /usr/lib/runlayer/run-aiwatch-update.sh (offset from quarter-hour scans):
  • Sources the same root-only credentials file and runs the packaged updater, which asks Runlayer for this device’s target version and installs it if different. Run sudo aiwatch update-now to start the same cycle immediately.
  • Waits for any in-progress scan to finish before upgrading, so a mid-scan upgrade is safe. Output goes to the runlayer-aiwatch syslog tag.

Verify

On a test machine after configuring both files:
Then in the Runlayer dashboard, go to Shadow AI → Devices: the device appears with OS = Linux, Detect = Active, and Protect / Enforce / Sessions = Disabled within about 15 minutes. Disabled endpoint modes and Sessions are the correct Detect-only state on Linux.

Updates

Automatic updates are always on. Each hourly check asks Runlayer for this device’s resolved target version. Exact equality is a no-op; any different target can advance or roll the device back. A manually installed version is replaced on the next hourly check unless your Client Updates policy pins that version. Existing installations need one ordinary package upgrade before the update wrapper and hourly cron entry are present. After that bootstrap upgrade, managed updates are automatic.
The first automatic update cannot install its own cron wrapper. Devices on an older package need one manual config-management package upgrade to a version that includes run-aiwatch-update.sh; subsequent updates are automatic.
Automatic updates are variant-aware. Each package records its build variant, and the updater only ever installs packages of the same variant: a standard device gets standard packages, a legacy device gets glibc 2.17 packages, and if no matching-variant artifact exists the check is a quiet no-op. Only a manual or configuration-management install moves a device between variants. Before root installation, AI Watch verifies the download’s SHA-256 checksum, declared size, and downloaded bytes against the published target, then verifies the native package name, version, and architecture with dpkg-deb or rpm. Verify manually downloaded artifacts with SHA256SUMS. You can still upgrade through configuration management (Ansible, Salt, Puppet, etc.) by installing a newer .deb / .rpm. The same install commands upgrade in place. Your edited /etc/runlayer/aiwatch/config.json and credentials files are preserved across upgrades because they use noreplace config semantics.

Uninstall

Removing the package deletes /etc/cron.d/runlayer-aiwatch immediately, so neither the scan nor update schedule keeps firing. Edited config files under /etc/runlayer/aiwatch/ remain unless you purge (sudo apt-get purge runlayer-aiwatch on Debian/Ubuntu).

Troubleshooting

  • The wrapper exits quietly when RUNLAYER_API_KEY is missing from /etc/runlayer/aiwatch/credentials — confirm the key is set and the file is readable by root.
  • Confirm a cron daemon is running (systemctl status cron or systemctl status crond).
  • Run sudo /usr/lib/runlayer/run-aiwatch-scan.sh; echo $? and check journalctl -t runlayer-aiwatch for per-user errors.
  • Verify the device can reach your tenant host over HTTPS (443).
Either RUNLAYER_API_KEY is not configured (the unconfigured-device gate), or a scan/update job currently holds the shared lock — overlapping runs skip instead of queueing. Wait for it to finish and retry.
  • Confirm the hourly line exists in /etc/cron.d/runlayer-aiwatch and a cron daemon is running.
  • Run sudo /usr/lib/runlayer/run-aiwatch-update.sh; echo $? to check immediately. This can install the version selected by your Runlayer tenant.
  • Check journalctl -t runlayer-aiwatch for download, checksum, package-identity, or native-installer errors.
Expected. Linux is Detect-only: there are no hooks, endpoint modes, Sessions, or browser extension. Only macOS and Windows support those features.