Skip to content

Deploy the Endpoint Agent

How to roll the endpoint agent to real user machines, and what to arrange before you start. Read the fleet-rollout section before deploying at scale — two of the items there are easier to arrange in advance than to explain afterwards.

Prerequisites

Requirement Detail
Python Linux: the system python3 must be 3.12 or newer (the installer refuses older: mitmproxy needs 3.12). Ubuntu 24.04 and Debian 13 qualify; Ubuntu 22.04 (3.10) does not. The macOS package and the Windows bundle carry their own Python
python3-venv Debian/Ubuntu only — a separate package. apt install python3-venv
Privileges root / Administrator. The installer writes to system service directories
Disk ~4 GB free (virtualenv, logs, and a 2.2 GB known-good hash corpus)
Network HTTPS egress to the control plane and the corpus bucket (below)

Network egress

Allow both, or the agent installs cleanly and then quietly stops receiving detection data:

Destination Port Purpose
Your control plane 443 Enrollment, policy, telemetry, commands
*.your-objectstorage.com 443 Signed hash corpora (NSRL known-good, malware)

A blocked corpus URL is not an obvious failure. The agent keeps running on its last good corpus and reports the corpus as stale in its heartbeat — which is the intended behaviour, but only helps if someone is watching the Endpoints view for it.

Install

Download the package and issue a one-time bootstrap token from the customer portal (SDK & Onboarding), then:

unzip -q cyberarmor-endpoint-agent.zip -d cyberarmor-agent
cd cyberarmor-agent
sudo python3 installer.py install \
  --control-plane-url https://your-control-plane \
  --tenant-id your-tenant-id \
  --bootstrap-token cabt_...

The token is redeemed into an install-scoped credential during setup, so no shared tenant secret is embedded on the endpoint. It is shown once and expires.

Linux: the local decision engine

On Linux the same installer.py install installs two systemd services:

Unit What it is
cyberarmor-endpoint the agent (monitors, policy sync, telemetry, heartbeat)
cyberarmor-local-engine the local decision engine: detection scans, tenant policy from the signed policy bundle, and the URL Trust Gate's network-free half, decided on the endpoint

The engine runs as root for file ownership only, with no capabilities, a read-only filesystem except its own state, and loopback-only networking. When it is healthy, the local proxy and the prompt hooks take its answer and do not ask the server; the server is asked only when the engine cannot answer (not running, refused, or below the tier your tenant requires). Detonation, policy sync, telemetry, audit and updates stay with the server.

Local ports and sockets on a Linux endpoint:

Where Who listens Who connects
127.0.0.1:48520 (TCP, loopback only) cyberarmor-local-engine the browser extensions; the proxy and hooks on builds before the authenticated socket
/var/lib/cyberarmor/local_engine.sock (Unix socket, root-owned directory) cyberarmor-local-engine, on builds with the authenticated socket the local proxy and prompt hooks, which accept the answer only from a root-owned listener
127.0.0.1:8888 (default) the per-user local proxy, if installed apps routed through it

Files: /var/lib/cyberarmor/local_engine_token (0644, the caller token), /var/lib/cyberarmor/ (status, posture, policy bundle), /etc/cyberarmor/local-models/ (model packs, 0700), /var/log/cyberarmor/local-engine.{log,err} (rotated by /etc/logrotate.d/cyberarmor-local-engine, 10 MiB × 4).

Check it:

systemctl status cyberarmor-local-engine
sudo systemd-analyze security cyberarmor-local-engine   # 1.7 "OK" where measured
cat /etc/cyberarmor/local_engine_deferred 2>/dev/null   # present only if it failed to start

What has been tested, and how. Installed and driven end to end in systemd containers: Ubuntu 24.04 and Debian 13 on aarch64 (Docker Desktop, Apple silicon), and Ubuntu 24.04 on x86_64 (the linux-local-engine CI job on a self-hosted runner), 2026-10-12. A scan and a signed-bundle policy decision, asked as an unprivileged user through the same client the proxy uses, came back decided_by: local with zero requests to the server; an upgrade restarted the engine; uninstall --purge left nothing. Not yet tested: a physical or virtual Linux desktop (GNOME/KDE proxy settings, browser trust store), the model tier (the Linux bundle does not yet carry the inference runtime, so Linux decides at the rules tier), and other distributions. Fedora/RHEL are expected to work where python3 is 3.12+ but have not been run.

macOS: grant Full Disk Access

Required. Skipping it produces an agent that reports healthy while monitoring nothing.

~/Documents, ~/Downloads, and ~/Desktop are TCC-protected. A daemon without Full Disk Access receives no file events from them at all — no error, no warning in the logs, heartbeats flowing normally. The endpoint looks protected and is not.

  1. System Settings → Privacy & Security → Full Disk Access
  2. Click +, press Cmd+Shift+G, enter /usr/local/cyberarmor/.venv/bin/, and add python3
  3. Restart the agent — the grant does not apply to the running process:
sudo launchctl kickstart -k system/ai.cyberarmor.endpoint

:::note If python3 is greyed out and unselectable

macOS will not grant Full Disk Access to a symlink, and endpoints installed before 2026-08-11 have one there — python3 → python3.14 → /Library/Frameworks/…. The installer now builds the venv with --copies, so a reinstall puts a real binary at that path and scopes the grant to this agent.

Failing that, grant it to whatever the link resolves to (readlink -f /usr/local/cyberarmor/.venv/bin/python3) — but that gives Full Disk Access to every script that interpreter runs, machine-wide.

:::

The label is ai.cyberarmor.endpoint. Earlier revisions of this page said ai.cyberarmor.endpoint-agent, which has never existed: bootout answered "Could not find specified service" and bootstrap "No such file or directory", so the agent was never restarted and the grant silently did not take effect.

Verify

Do not rely on "the install said OK". Prove it:

sudo python3 /usr/local/cyberarmor/disk_access.py

Lists every monitored directory and exits non-zero if any is unreadable. For a deeper check that change notifications actually arrive — a separate permission from being able to read the directory:

sudo python3 /usr/local/cyberarmor/disk_access.py --canary

This writes a temporary dotfile into each monitored directory, confirms the event is observed, and removes it.

Then confirm enrollment in the customer portal under Endpoints. The host appears within about a minute, with Monitoring showing OK rather than Degraded.

Coexisting with an existing EDR

Most organisations already run CrowdStrike, SentinelOne, or Microsoft Defender. The CyberArmor.AI agent monitors files, processes, and optionally the clipboard — behaviour that is, by design, difficult to distinguish from malware.

Arrange an exclusion before deployment, not after. Expect the incumbent to quarantine the agent, block its execution, or throttle it. Supply your security team with:

  • the install directory (/usr/local/cyberarmor or %PROGRAMFILES%\CyberArmor)
  • the service name (ai.cyberarmor.endpoint)
  • the process name (cyberarmor-agent)

Two endpoint agents on one machine is a supported configuration, but not an automatic one.

The local proxy is a separate decision

The endpoint agent and the local proxy are different installs with very different footprints.

The proxy provides in-line AI Trust Gate enforcement, and to do so it changes the system proxy settings and installs a CA certificate. In a regulated environment that is a security-review item and often a change-control ticket. It has also historically interfered with captive-portal sign-in on public wifi — an included watchdog handles that, but it is a moving part.

The agent delivers endpoint detection, patch management, A-BOM, and shadow-AI discovery without it. Deploy the agent first, and treat the proxy as a deliberate second phase.

Fleet rollout

Two things worth planning for a large deployment:

First-sync bandwidth. Each endpoint downloads the known-good corpus once — currently ~2.2 GB. Across 800 endpoints that is roughly 1.76 TB. Stage the rollout rather than enrolling a whole site on one morning. Subsequent updates are deltas and are small.

Exclusion approval lead time. See above. It is usually the longest pole, and it is entirely a paperwork problem, so start it first.

Uninstall

sudo python3 /usr/local/cyberarmor/installer.py uninstall

Add --purge to remove configuration and logs as well. On macOS the per-user clipboard helper, if installed, is removed separately — the uninstaller prints the exact commands.

On Linux the install path is /opt/cyberarmor: sudo python3 /opt/cyberarmor/installer.py uninstall. It stops and removes the local engine first (unit, logrotate policy, token, socket) and stops without deleting anything if the engine will not stop. --purge also removes /var/lib/cyberarmor. The per-user Linux proxy is removed with /opt/cyberarmor/uninstall_local_proxy_linux.sh, run as that user before the agent, since the script lives in the install tree.

Troubleshooting

Symptom Cause
Endpoint never appears in Endpoints Wrong --tenant-id, or control-plane egress blocked
Monitoring: Degraded Full Disk Access not granted — run disk_access.py
No file events despite Monitoring: OK Run the --canary check; readability and event delivery are separate grants
Corpus version stays at 0 Object-storage egress blocked, or no manifest published yet
python3 -m venv fails on Ubuntu Install python3-venv

See also Endpoint Agent, Endpoint Detection, and Patch Management.