Skip to content

Installation

OpenSCM is designed to be lightweight with minimal dependencies, running on everything from enterprise servers to edge devices.

Prerequisites

Requirement Details
Operating System Linux, Windows 10+, FreeBSD, macOS, Arch Linux
Architecture x86_64, ARM64, ARMv7, i686, RISC-V 64, PowerPC 64 LE, s390x, LoongArch64
Privileges sudo (Linux/macOS) or Administrator (Windows)

Server Installation

The server only needs to be installed once on a central host.

1. Set up the repository:

curl -sS https://repo.openscm.io/openscm.gpg | sudo gpg --dearmor -o /usr/share/keyrings/openscm.gpg
echo "deb [signed-by=/usr/share/keyrings/openscm.gpg] https://repo.openscm.io/stable/debian stable main" | sudo tee /etc/apt/sources.list.d/openscm.list
sudo apt update

2. Install:

sudo apt install scmserver

1. Set up the repository:

sudo tee /etc/yum.repos.d/openscm.repo <<EOF
[openscm]
name=OpenSCM Stable
baseurl=https://repo.openscm.io/stable/redhat/
enabled=1
gpgcheck=1
gpgkey=https://repo.openscm.io/openscm.gpg
EOF

2. Install:

sudo yum install scmserver

1. Set up the repository:

sudo zypper addrepo https://repo.openscm.io/stable/redhat/ openscm
sudo zypper refresh

2. Install:

sudo zypper install scmserver
docker run -d \
  --name openscm \
  -p 8000:8000 \
  -v openscm_config:/etc/openscm \
  -v openscm_data:/var/lib/openscm \
  openscm/scmserver:latest

Or using Docker Compose:

version: '3.8'

services:
  openscm:
    image: openscm/scmserver:latest
    container_name: openscm
    restart: unless-stopped
    ports:
      - "8000:8000"
    volumes:
      - openscm_data:/var/lib/openscm
      - openscm_config:/etc/openscm

volumes:
  openscm_data:
  openscm_config:

Volume Backup

Always mount the /etc/openscm volume. If it is lost all registered agents will need to re-register.

Download the installer from the Downloads page and run the setup wizard. The server will be registered as a Windows Service automatically.

Access the dashboard at http://localhost:8000 after installation.

Prefer a direct download? Get the latest packages from the Downloads page.

# Debian/Ubuntu example
sudo dpkg -i scmserver_0.8.0-1_amd64.deb

Agent Installation

Install the agent on every system you want to monitor. It is a single static binary with no runtime dependencies.

Linux, macOS and FreeBSD — one command

curl -fsSL https://repo.openscm.io/install.sh | sh -s -- \
    --server https://your-openscm-server

The script detects your distribution and CPU, installs the right package using your own package manager, writes the agent config, and starts the service. On Debian and RHEL-family systems it adds the OpenSCM package repository, so apt upgrade / dnf upgrade keeps the agent current afterwards.

Add --dry-run to see exactly what it would do without changing anything, and --help for the full list of options.

Option Description Default
--server URL Your OpenSCM server URL required
--organization ID Organization / tenant identifier default
--channel NAME stable or testing stable
--version X.Y.Z Pin a specific version newest published
--heartbeat SECS Check-in interval 300
--token TOKEN Enrollment token — auto-approves this system
--dry-run Print every action, change nothing
--uninstall Remove the agent
--purge With --uninstall: also remove config, logs and the repository

Rolling out to many machines

Pass --token with an enrollment token and the system is approved automatically instead of waiting in Systems as pending. Mint tokens in the UI under Enrollment.

The token is a credential: prefer the OPENSCM_ENROLLMENT_TOKEN environment variable over the command line, which is visible in ps and recorded in shell history.

export OPENSCM_ENROLLMENT_TOKEN=...
curl -fsSL https://repo.openscm.io/install.sh | sh -s -- \
    --server https://your-openscm-server

SaaS users

Pass --organization with your organization identifier. Without it the agent enrolls into default, which is not your organization. The command shown in the first-run tour already has your value filled in.

Supported: Debian, Ubuntu, RHEL, Fedora, CentOS, Rocky, Alma, openSUSE, Arch, FreeBSD and macOS — on every architecture the repository publishes. The script picks the correct one for the machine it runs on.

Removing the agent

curl -fsSL https://repo.openscm.io/install.sh | sh -s -- --uninstall

Stops the service and removes the package, leaving the config and the OpenSCM package repository in place. Add --purge to remove those too.

What --purge will not touch

/etc/openscm is shared with the server: it holds scmserver.config and keys/scmserver.key. --purge removes only the agent's own files, and if scmserver is installed it also leaves the package repository and log directory alone rather than cutting the server off from updates.

The system stays listed in Systems until you delete it there; it simply stops checking in.

Windows

Download the installer from the Downloads page and run the setup wizard. The agent is registered as a Windows Service automatically, and the wizard prompts for the server URL.

Installing manually

The one-line installer is a convenience, not a requirement — it does exactly what the steps below do. Use these if you need to inspect each step, are building your own automation, or are working offline.

curl -sS https://repo.openscm.io/openscm.gpg | sudo gpg --dearmor -o /usr/share/keyrings/openscm.gpg
echo "deb [signed-by=/usr/share/keyrings/openscm.gpg] https://repo.openscm.io/stable/debian stable main" | sudo tee /etc/apt/sources.list.d/openscm.list
sudo apt update
sudo apt install scmclient
sudo tee /etc/yum.repos.d/openscm.repo <<EOF
[openscm]
name=OpenSCM
baseurl=https://repo.openscm.io/stable/redhat
enabled=1
gpgcheck=1
gpgkey=https://repo.openscm.io/openscm.gpg
EOF
sudo yum install scmclient
sudo zypper addrepo https://repo.openscm.io/stable/redhat/ openscm
sudo zypper refresh
sudo zypper install scmclient
curl -sS https://repo.openscm.io/openscm.gpg -o /tmp/openscm.gpg
sudo pacman-key --add /tmp/openscm.gpg
sudo pacman-key --lsign-key 8A39E120F8B52DBB
sudo pacman -U https://repo.openscm.io/stable/arch/scmclient-0.8.0-1-x86_64.pkg.tar.zst

Published for x86_64, aarch64, armhf, ppc64le and riscv64. For i686, s390x and LoongArch64 use the Debian or RPM packages.

pkg add https://repo.openscm.io/stable/freebsd/scmclient-0.8.0-1-freebsd-amd64.pkg
curl -LO https://repo.openscm.io/stable/macos/scmclient_0.8.0-1_macos.pkg
sudo installer -pkg scmclient_0.8.0-1_macos.pkg -target /

Every architecture is listed on the Downloads page if you need a specific file. After a manual install, follow Post-Installation Setup below — the one-line installer does those steps for you.


Post-Installation Setup

Using the one-line installer?

Steps 1 and 2 are done for you — the agent is already configured and running. Go straight to 3. Approve the Agent, which is always required.

1. Configure the Agent

Edit the config file and point it to your server:

sudo vi /etc/openscm/scmclient.config
vi /usr/local/etc/openscm/scmclient.config
sudo vi /usr/local/etc/openscm/scmclient.config

Use the registry editor or the installer wizard to set the server URL.

[server]
url = "https://your-openscm-server.com"  # Your server URL
organization = "default"                    # Organization identifier

[client]
heartbeat = "300"                        # Check-in interval in seconds
loglevel = "info"

2. Restart the Agent

sudo systemctl restart scmclient
sudo systemctl enable scmclient
service scmclient restart
sudo launchctl bootout system/io.openscm.scmclient
sudo launchctl bootstrap system /Library/LaunchDaemons/io.openscm.scmclient.plist
Restart-Service OpenSCMClient

3. Approve the Agent

Once the agent starts it will send a registration request to the server.

  1. Log in to the OpenSCM dashboard
  2. Navigate to Systems
  3. Find the pending system and click Approve

The agent is now active and will begin receiving compliance tests.

First-run Setup

On a fresh installation, the dashboard will walk you through creating your admin account on the first visit. No default credentials are set.


Verify Installation

# Check server status
sudo systemctl status scmserver

# Check agent status
sudo systemctl status scmclient

# View logs
sudo journalctl -u scmserver -f
sudo journalctl -u scmclient -f
# Check agent status
service scmclient status

# View logs
tail -f /var/log/openscm/scmclient.log
# Check agent status
sudo launchctl list | grep openscm

# View logs
tail -f /var/log/openscm/scmclient.log
# Check service status
Get-Service OpenSCMServer
Get-Service OpenSCMClient

Health Probes

The server exposes two public, unauthenticated HTTP endpoints for use by load balancers, container orchestrators, and uptime monitors. Both are whitelisted by the init-guard middleware so they answer even before the first-run setup is complete — which means a Kubernetes pod can come up cleanly during a fresh install or a rolling upgrade with mid-flight migrations.

GET /health — liveness

"Is the process alive and accepting HTTP?" Returns immediately, no database query, no work.

$ curl -i http://localhost:8000/health
HTTP/1.1 200 OK
content-type: application/json

{"status":"ok"}

Use for Kubernetes livenessProbe, the Docker image's HEALTHCHECK, and basic load-balancer pool-membership decisions. If /health ever stops returning 200, the orchestrator should restart the container.

GET /ready — readiness

"Is the server able to serve real user traffic?" Returns 200 OK only when the database pool answers a trivial query and the schema is set up. Returns 503 Service Unavailable otherwise.

Response When What it means
200 OK with {"status":"ok","schema_version":N} DB reachable, schema present Send traffic
503 with {"status":"db_unavailable"} DB pool can't SELECT 1 Hold traffic; check disk / DB lock
503 with {"status":"setup_pending"} Fresh install — /install not completed yet Hold traffic until the first-run wizard is finished

Use for Kubernetes readinessProbe so the load balancer keeps the old pod in rotation while a rolling deploy runs migrations on the new one.

Example wiring

livenessProbe:
  httpGet:
    path: /health
    port: 8000
  periodSeconds: 10
  failureThreshold: 3
readinessProbe:
  httpGet:
    path: /ready
    port: 8000
  periodSeconds: 5
  failureThreshold: 3
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -fsS http://localhost:8000/health || exit 1
# docker-compose.yml
services:
  scmserver:
    image: openscm/scmserver:latest
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost:8000/health"]
      interval: 30s
      timeout: 3s
      retries: 3
backend openscm
    option httpchk GET /ready
    http-check expect status 200
    server srv1 10.0.0.1:8000 check inter 5s fall 3 rise 2
    server srv2 10.0.0.2:8000 check inter 5s fall 3 rise 2

Add nginx-plus / ngx_http_upstream_check_module:

upstream openscm {
    server 10.0.0.1:8000;
    server 10.0.0.2:8000;
    check interval=5000 rise=2 fall=3 timeout=3000 type=http;
    check_http_send "GET /ready HTTP/1.0\r\n\r\n";
    check_http_expect_alive http_2xx;
}

Let the server compress — don't strip Accept-Encoding

Since 0.8.0 OpenSCM compresses its own responses (gzip/brotli) and serves static assets with ETag + Cache-Control, which is most of the reason a page costs ~290 KB instead of ~4.8 MB. Both depend on headers surviving your reverse proxy:

  • Forward the client's Accept-Encoding header. Some proxy configurations clear it, which silently disables compression.
  • Don't strip ETag or Cache-Control from responses, or every navigation re-downloads the full asset set.
  • You do not need gzip on in Nginx for OpenSCM's own responses — it will not double-compress something already carrying Content-Encoding. Leaving it on is harmless.

Both endpoints bypass the init-guard

Unlike every other route on the server, /health and /ready answer even before /install has been completed. This is deliberate so that a Kubernetes pod can be marked alive (and the load balancer can wait for it to become ready) during the brief window between container start and the first-run admin completing the setup wizard.