Running
Opservant can be deployed as a Docker container, a systemd service on a Linux host, or a Kubernetes DaemonSet. Choose the method that best fits your infrastructure.
Prerequisites
Before deploying, ensure you have:
- An agent registration token generated from the S4E dashboard under Settings > Agents > Add Agent.
- The S4E platform URL (e.g.,
https://platform.s4e.ioor your on-premises endpoint). - Outbound HTTPS (port 443) access from the host to the platform URL.
1. Docker
Quick start
docker run -d \
--name opservant \
--restart unless-stopped \
--network host \
-e S4E_API_URL=https://platform.s4e.io \
-e S4E_AGENT_TOKEN=<registration-token> \
-e S4E_AGENT_ID=<agent-id> \
-v opservant-data:/var/lib/opservant \
s4e/opservant:latest
Note
Using --network host gives the agent visibility into the host's network stack, which is required for accurate network discovery. If host networking is not an option, ensure the container can reach target subnets through Docker network configuration.
Docker Compose
version: "3.9"
services:
opservant:
image: s4e/opservant:latest
container_name: opservant
restart: unless-stopped
network_mode: host
environment:
S4E_API_URL: https://platform.s4e.io
S4E_AGENT_TOKEN: ${S4E_AGENT_TOKEN}
S4E_AGENT_ID: ${S4E_AGENT_ID}
S4E_LOG_LEVEL: INFO
volumes:
- opservant-data:/var/lib/opservant
- /etc/opservant/config.yaml:/etc/opservant/config.yaml:ro
volumes:
opservant-data:
The named volume opservant-data persists agent state (registration certificates, local task queue, SQLite database) across container restarts and upgrades.
2. systemd
Installation
Download the latest release archive and extract it:
curl -LO https://releases.s4e.io/opservant/latest/opservant-linux-amd64.tar.gz
tar -xzf opservant-linux-amd64.tar.gz -C /opt/opservant
chmod +x /opt/opservant/bin/opservant
Create the configuration directory and place your config file:
Edit /etc/opservant/config.yaml to set your platform URL, agent token, and agent ID (see the configuration reference below).
Unit file
Create /etc/systemd/system/opservant.service:
[Unit]
Description=Opservant S4E Agent
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/opt/opservant/bin/opservant --config /etc/opservant/config.yaml
Restart=on-failure
RestartSec=10
User=opservant
Group=opservant
LimitNOFILE=65536
Environment=S4E_LOG_LEVEL=INFO
[Install]
WantedBy=multi-user.target
Service management
sudo systemctl daemon-reload
sudo systemctl enable opservant
sudo systemctl start opservant
sudo systemctl status opservant
journalctl -u opservant -f
Tip
Create a dedicated opservant system user with no login shell (useradd -r -s /usr/sbin/nologin opservant) to follow the principle of least privilege.
3. Kubernetes DaemonSet
The DaemonSet ensures one Opservant pod runs on every selected node, which is ideal for scanning each node's local network segment.
Manifest
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: opservant
namespace: s4e-agents
labels:
app: opservant
spec:
selector:
matchLabels:
app: opservant
template:
metadata:
labels:
app: opservant
spec:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
serviceAccountName: opservant
nodeSelector:
s4e.io/scan-agent: "true"
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: opservant
image: s4e/opservant:latest
env:
- name: S4E_API_URL
value: "https://platform.s4e.io"
- name: S4E_AGENT_TOKEN
valueFrom:
secretKeyRef:
name: opservant-credentials
key: token
- name: S4E_AGENT_ID
valueFrom:
fieldRef:
fieldPath: spec.nodeName
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
volumeMounts:
- name: state
mountPath: /var/lib/opservant
livenessProbe:
httpGet:
path: /healthz
port: 9191
initialDelaySeconds: 15
periodSeconds: 30
readinessProbe:
httpGet:
path: /readyz
port: 9191
initialDelaySeconds: 5
periodSeconds: 10
volumes:
- name: state
emptyDir: {}
RBAC
The agent pod requires a ServiceAccount with minimal permissions. It does not need access to the Kubernetes API - the ServiceAccount exists solely to pull image secrets and mount volumes.
Warning
Do not grant the Opservant ServiceAccount cluster-admin or broad RBAC roles. The agent operates at the network level and does not interact with the Kubernetes control plane.
Node selector
Label target nodes to control where the DaemonSet schedules pods:
Configuration File
The primary configuration file is located at /etc/opservant/config.yaml. Command-line flags and environment variables override values in this file.
platform:
api_url: https://platform.s4e.io
agent_id: agent-eu-west-01
token: <registration-token>
agent:
heartbeat_interval: 30s
task_concurrency: 4
scratch_dir: /tmp/opservant
logging:
level: INFO
output: stdout
file: /var/log/opservant/agent.log
proxy:
https: ""
Environment Variable Reference
| Variable | Description | Default |
|---|---|---|
S4E_API_URL |
Platform API endpoint | required |
S4E_AGENT_TOKEN |
One-time registration token | required |
S4E_AGENT_ID |
Unique agent identifier | hostname |
S4E_LOG_LEVEL |
Log verbosity (DEBUG, INFO, WARNING, ERROR, CRITICAL) |
INFO |
S4E_HEARTBEAT_INTERVAL |
Heartbeat frequency in seconds | 30 |
S4E_TASK_CONCURRENCY |
Max parallel executor tasks | 4 |
S4E_SCRATCH_DIR |
Temporary working directory for executors | /tmp/opservant |
S4E_PROXY_HTTPS |
HTTPS proxy URL for outbound connections | none |
S4E_TLS_CA_CERT |
Path to custom CA certificate bundle | system default |
Health Check Endpoint
The agent exposes a local HTTP health endpoint on port 9191 (configurable via S4E_HEALTH_PORT).
| Path | Purpose |
|---|---|
/healthz |
Returns 200 OK when the agent process is alive |
/readyz |
Returns 200 OK when the agent is registered and the WebSocket channel is connected |
/metrics |
Prometheus-compatible metrics (task counts, executor durations, heartbeat status) |
Upgrading the Agent
Docker
Pull the new image and recreate the container. The persistent volume retains agent state.
docker pull s4e/opservant:latest
docker stop opservant && docker rm opservant
# Re-run the docker run command or docker compose up -d
systemd
Replace the binary and restart the service:
curl -LO https://releases.s4e.io/opservant/latest/opservant-linux-amd64.tar.gz
tar -xzf opservant-linux-amd64.tar.gz -C /opt/opservant
sudo systemctl restart opservant
Kubernetes
Update the image tag in the DaemonSet manifest and apply:
Tip
Enable the auto-update feature in the agent configuration (agent.auto_update: true) to let the platform push verified updates to agents without manual intervention.