Linux agent
Python-based agent that runs outbound over WebSocket to the platform. Managed by systemd. Suitable for anywhere you can run Python 3.10+ β dedicated Linux boxes, EC2 instances, LXC containers, Kubernetes pods (single-replica).
Install
- In the Pentestas UI, go to Settings β Agents β New agent.
- Name it (e.g.
corp-fra-01) and add the public IPs it will connect from to the allowlist. - Copy the install command.
- Run on the target host:
curl -fsSL https://app.pentestas.com/agent/install.sh | sudo bash -s -- --key pa_YOUR_KEY
The installer:
- Creates
/opt/pentestas-agent/with a Python virtualenv. - Installs
websockets,httpx,cryptography, and optionallymitmproxy. - Drops an env file at
/opt/pentestas-agent/config(chmod 0600) holding the key. - Installs a systemd unit at
/etc/systemd/system/pentestas-agent.service. - Enables + starts the service.
Flags accepted by the installer:
--key <AGENT_KEY>(required)--url <wss://β¦>β override the platform URL (defaultwss://app.pentestas.com/api/agents/ws)--prefix <DIR>β install location (default/opt/pentestas-agent)--no-browserβ skip mitmproxy (no browser launcher support); smaller footprint--dry-runβ print commands, don't execute
Verify
systemctl status pentestas-agent
journalctl -u pentestas-agent -f
You should see:
[INFO] pentestas-agent 0.3.0 starting (caps=network_scan,web_scan,browser_launcher)
[INFO] platform=wss://app.pentestas.com/api/agents/ws
[INFO] connected to wss://app.pentestas.com/api/agents/ws
[INFO] welcome: Connected to Pentestas platform
In the UI, the agent row flips from Pending β Connected within 5 seconds.
Sub-commands
The agent binary supports three sub-commands:
| Sub-command | Purpose |
|---|---|
connect |
Long-lived connection loop (default, used by systemd) |
version |
Print agent version + discovered capabilities |
probe |
One-shot diagnostic: platform URL, key presence, detected browsers |
Run manually to debug:
sudo -u pentestas /opt/pentestas-agent/venv/bin/python \
-m scanner.agent.agent probe
Capabilities detected at runtime
The agent advertises its capabilities to the platform on each connect:
- network_scan β always available (uses built-in asyncio TCP scanner).
- web_scan β advertised if the
DirectScanEnginemodule is importable (present in the Docker image, not in the slim PyPI install). - browser_launcher β advertised if
mitmproxyis installed and at least one browser is discovered on the host.
Dispatch endpoints refuse to send jobs that don't match the agent's advertised capabilities, so the UI never sends a web-scan job to a network-only agent.
Updating
Re-run the installer with the same key β the tarball is re-downloaded and systemd is restarted. No key rotation needed.
sudo systemctl stop pentestas-agent
curl -fsSL https://app.pentestas.com/agent/install.sh | sudo bash -s -- --key pa_YOUR_KEY
Uninstall
sudo systemctl disable --now pentestas-agent
sudo rm -rf /opt/pentestas-agent /etc/systemd/system/pentestas-agent.service
sudo systemctl daemon-reload
Key rotation is separate β do it in the UI, then re-install.
Docker variant
For users who want the full scan engine without a venv on the host, deploy via Docker:
docker run -d --restart=always \
--name pentestas-agent \
-e PENTESTAS_AGENT_KEY=pa_YOUR_KEY \
-v pentestas-agent-state:/var/lib/pentestas-agent \
pentestas/agent:latest
Same protocol. Trades disk footprint (~500 MB image) for a guaranteed-consistent engine version.
Troubleshooting
See Troubleshooting for the common cases (wrong IP in allowlist, WebSocket blocked, clock skew).