Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Self-hosted Machine install

This page covers the host-side setup shared by GitHub Actions Self-hosted Machine Runners and GitLab CI/CD Self-hosted Docker executors.

In self-hosted deployments, install the cicd-sensor Agent and Docker proxy on the runner host and operate them with cicd-sensor Manager. For GitHub Actions-specific hook setup, see GitHub Actions self-hosted. For the GitLab CI/CD runner model, see GitLab CI/CD self-hosted.

OS / Linux prerequisites

  • Linux kernel:
    • amd64: 5.15 or later.
    • arm64: 6.1 or later. The arm64 lower bound is set by upstream Linux because BPF trampoline / fentry attach landed on arm64 only in 6.0+; on older arm64 kernels the agent fails to attach with create raw tracepoint: not supported.
  • cgroup v2.
  • systemd.
  • dockerd.

Network requirements

Allow outbound HTTPS from the Agent host to the Manager URL.

DestinationPurpose
Manager URLFetch config and rules, and send Summary Logs, Detection Logs, and Runtime Event Logs

When using Manager, the Agent does not connect directly to the public baseline rule registries or the host used to fetch Sigstore root certificates. The Manager fetches and verifies baseline rules.

Install path

cicd-sensor releases are available from cicd-sensor/cicd-sensor releases.

This guide uses /opt/cicd-sensor as the fixed install path for cicd-sensor binaries and hook scripts.

The release tarball ships architecture-suffixed binaries; rename them to the canonical names below so the systemd units resolve them:

sudo install -d -m 0755 /opt/cicd-sensor
sudo tar -xzf cicd-sensor_<version>_linux_<arch>.tar.gz -C /opt/cicd-sensor
sudo mv /opt/cicd-sensor/cicd-sensor-linux-<arch> /opt/cicd-sensor/cicd-sensor
sudo mv /opt/cicd-sensor/cicd-sensor-manager-linux-<arch> /opt/cicd-sensor/cicd-sensor-manager
sudo mv /opt/cicd-sensor/cicd-sensorctl-linux-<arch> /opt/cicd-sensor/cicd-sensorctl
/opt/cicd-sensor/
  cicd-sensor
  cicd-sensor-manager
  cicd-sensorctl

User / root execution model

This guide runs the Agent and Docker proxy as root.

The Agent needs root-equivalent privileges to attach eBPF programs, read cgroup state, and trace process activity. The Docker proxy and Agent must also run with the same privileges because the proxy uses peer UID checks when calling Agent internal endpoints.

Manager token

Create the manager token source file under /etc/cicd-sensor/.

sudo install -d -m 0750 /etc/cicd-sensor
echo "MANAGER_TOKEN_HERE" | sudo tee /etc/cicd-sensor/manager-token >/dev/null
sudo chmod 0600 /etc/cicd-sensor/manager-token
sudo chown root:root /etc/cicd-sensor/manager-token

For systemd, load it as a service credential:

[Service]
LoadCredential=manager_token:/etc/cicd-sensor/manager-token

systemd copies the source file into a service-specific runtime credential directory and sets CREDENTIALS_DIRECTORY. Pass that runtime copy to cicd-sensor with --manager-token-file ${CREDENTIALS_DIRECTORY}/manager_token. The complete service example below includes both settings.

Sensor startup

Run the Agent as a systemd service. Set --provider for the target environment.

Environment--provider--runner
GitHub Actions Self-hosted Machine Runnergithubmachine
GitLab CI/CD Self-hosted Docker executorgitlabmachine
# /etc/systemd/system/cicd-sensor-agent.service
[Unit]
Description=cicd-sensor Agent
After=network-online.target
Wants=network-online.target
RefuseManualStop=yes
IgnoreOnIsolate=yes

[Service]
Type=simple
RuntimeDirectory=cicd-sensor
RuntimeDirectoryMode=0755
LoadCredential=manager_token:/etc/cicd-sensor/manager-token
ExecStart=/opt/cicd-sensor/cicd-sensor agent start \
  --provider github \
  --runner machine \
  --manager-url https://cicd-sensor-manager.example.com \
  --manager-token-file ${CREDENTIALS_DIRECTORY}/manager_token
Restart=always
RestartSec=5s
NoNewPrivileges=yes
PrivateTmp=yes
OOMScoreAdjust=-1000
KillMode=mixed
TimeoutStopSec=5s

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now cicd-sensor-agent.service

For GitLab CI/CD, change --provider github to --provider gitlab.

RefuseManualStop=yes rejects manual systemctl stop. Remove it if your maintenance workflow normally uses stop / restart.

Docker proxy

Self-hosted Machine Runners assume dockerd. Place cicd-sensor proxy dockerd in front of the Docker socket so cicd-sensor can observe container creation.

After installation, workflows and runner-side Docker clients still connect to /run/docker.sock. /run/docker.sock is served by the cicd-sensor Docker proxy, and the real dockerd socket moves to /run/docker-upstream.sock.

docker client
  -> /run/docker.sock                 # cicd-sensor proxy
  -> /run/docker-upstream.sock        # real dockerd

Run the Docker proxy as the same user as the Agent, usually root. If the Agent and proxy run as different users, Agent internal endpoints reject proxy requests.

# /etc/systemd/system/cicd-sensor-docker-proxy.service
[Unit]
Description=cicd-sensor Docker proxy
After=cicd-sensor-agent.service docker.service
Requires=cicd-sensor-agent.service docker.service

[Service]
Type=simple
Group=docker
UMask=0117
ExecStartPre=/bin/rm -f /run/docker.sock
ExecStart=/opt/cicd-sensor/cicd-sensor proxy dockerd --provider github
Restart=on-failure
RestartSec=100ms

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now cicd-sensor-docker-proxy.service
docker info

For GitLab CI/CD, change --provider github to --provider gitlab.

Docker’s systemd socket unit commonly uses SocketMode=0660 and SocketGroup=docker. Because the cicd-sensor Docker proxy creates /run/docker.sock from a service process, this service uses Group=docker and UMask=0117 to produce the same root:docker / 0660 access model. Adjust these settings if your runner host manages Docker socket access differently.

Dockerd socket setting

dockerd can be installed and managed in several ways. This example assumes the runner host uses systemd docker.socket to manage the Docker socket.

Override the docker.socket listen path and move the real dockerd socket to /run/docker-upstream.sock.

# /etc/systemd/system/docker.socket.d/override.conf
[Socket]
ListenStream=
ListenStream=/run/docker-upstream.sock

Apply the override.

sudo systemctl daemon-reload
sudo systemctl restart docker.socket
sudo systemctl restart docker.service

Confirm that real dockerd responds on the upstream socket.

sudo docker -H unix:///run/docker-upstream.sock info

Optional: Linux security hardening

On Linux hosts that use AppArmor or SELinux, add an Agent profile / policy that matches the runner host distribution, policy model, and cicd-sensor features you enable.