Configuration
OpenSCM uses a platform-native approach to configuration. On Linux, FreeBSD, and macOS, configuration is handled via TOML files. On Windows, settings are stored in the System Registry to facilitate enterprise deployment via Group Policy (GPO).
Server Configuration
The scmserver manages the central database and agent authorizations.
Default Path: /etc/openscm/scmserver.config
Path: HKEY_LOCAL_MACHINE\SOFTWARE\OpenSCM\Server
| Value Name | Type | Description |
|---|---|---|
Port |
REG_SZ | Port for the server (e.g., 8000) |
LogLevel |
REG_SZ | Logging level (info, debug, etc.) |
TrustedProxies |
REG_SZ | Optional. Comma-separated; see Behind a proxy or CDN |
Fixed Paths
The SQLite database and key paths are fixed and cannot be changed via config.
| Resource | Linux | Windows |
|---|---|---|
| SQLite DB | /var/lib/openscm/scm.db |
C:\ProgramData\OpenSCM\Server\scm.db |
| Keys | /etc/openscm/keys/ |
C:\ProgramData\OpenSCM\Server\keys\ |
| Logs | /var/log/openscm/ |
C:\ProgramData\OpenSCM\Server\logs\ |
Database
OpenSCM uses SQLite — a single file embedded in the server process. No database server, no connection strings, no external dependencies.
The database file is created automatically on first run at the fixed path shown in the Fixed Paths table above. No [database] config is needed unless you want to acknowledge the path.
Setup wizard
On a fresh installation the first-run setup wizard initialises the database and creates the bootstrap admin account automatically.
Client Configuration
The scmclient agent handles heartbeats and local compliance scanning.
Default Path: /etc/openscm/scmclient.config
[server]
url = "http://localhost:8000" # URL of your OpenSCM Server
organization = "default" # Organization identifier
# enrollment_token = "oscm_…" # Optional: auto-approve this system at enrollment
[client]
heartbeat = "300" # Check-in interval in seconds
loglevel = "info" # debug | info | warn | error
cmd_enabled = false # Allow CMD tests to run (opt-in)
ps_enabled = false # Allow PowerShell tests to run (opt-in, Windows only)
Default Path: /usr/local/etc/openscm/scmclient.config
[server]
url = "http://localhost:8000" # URL of your OpenSCM Server
organization = "default" # Organization identifier
# enrollment_token = "oscm_…" # Optional: auto-approve this system at enrollment
[client]
heartbeat = "300" # Check-in interval in seconds
loglevel = "info" # debug | info | warn | error
cmd_enabled = false # Allow CMD tests to run (opt-in)
ps_enabled = false # Allow PowerShell tests to run (opt-in, Windows only)
Default Path: /usr/local/etc/openscm/scmclient.config
[server]
url = "http://localhost:8000" # URL of your OpenSCM Server
organization = "default" # Organization identifier
# enrollment_token = "oscm_…" # Optional: auto-approve this system at enrollment
[client]
heartbeat = "300" # Check-in interval in seconds
loglevel = "info" # debug | info | warn | error
cmd_enabled = false # Allow CMD tests to run (opt-in)
ps_enabled = false # Allow PowerShell tests to run (opt-in, Windows only)
Path: HKEY_LOCAL_MACHINE\SOFTWARE\OpenSCM\Client
| Value Name | Type | Description |
|---|---|---|
ServerURL |
REG_SZ | URL of the OpenSCM Server |
Organization |
REG_SZ | Organization identifier |
Heartbeat |
REG_SZ | Check-in interval in seconds |
LogLevel |
REG_SZ | Logging level |
CmdEnabled |
REG_SZ | Allow CMD tests to run (true / false) |
PsEnabled |
REG_SZ | Allow PowerShell tests to run (true / false) |
Fixed Paths
The key paths are fixed and cannot be changed:
| Resource | Linux | FreeBSD / macOS | Windows |
|---|---|---|---|
| Keys | /etc/openscm/keys/ |
/usr/local/etc/openscm/keys/ |
C:\ProgramData\OpenSCM\Client\keys\ |
| Logs | /var/log/openscm/ |
/var/log/openscm/ |
C:\ProgramData\OpenSCM\Client\logs\ |
Parameter Reference
Server Parameters
| Parameter | Default | Description |
|---|---|---|
server.port |
8000 |
Port the server listens on |
server.loglevel |
info |
Log verbosity: error, warn, info, debug |
server.trusted_proxies |
loopback and private ranges | Addresses allowed to tell the server who the client is. See below |
Behind a proxy or CDN
OpenSCM records the client's address in the audit log and uses it for the
sign-in rate limits. Behind a reverse proxy, the connection comes from the
proxy, and the real address arrives in the X-Forwarded-For header. Anyone
can send that header, so OpenSCM only believes it when the connection comes
from a trusted proxy.
By default, loopback (127.0.0.0/8, ::1) and the private ranges
(10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7) are trusted.
That covers nginx or Caddy on the same host or the same Docker network, and
needs no setting.
If something on a public address sits in front, such as Cloudflare or a cloud load balancer, list its ranges, together with your own proxy:
Setting the list replaces the defaults; it doesn't add to them. Without the
CDN's ranges, every visitor appears with the CDN's address, and visitors
share one sign-in rate limit. An empty list (trusted_proxies = []) trusts
nobody and ignores the header entirely, the right choice when nothing sits in
front of OpenSCM.
Make sure your proxy appends the client's address to X-Forwarded-For rather
than passing the client's own header through unchanged. Caddy does this by
default. In nginx:
Client Parameters
| Parameter | Default | Description |
|---|---|---|
server.url |
http://localhost:8000 |
OpenSCM server URL |
server.organization |
default |
Organization identifier |
server.enrollment_token |
(none) | Optional golden token (oscm_…) that auto-approves this system at enrollment. See Enrollment Tokens. Sent only at first registration. |
client.heartbeat |
300 |
Check-in interval in seconds |
client.loglevel |
info |
Log verbosity: error, warn, info, debug |
client.cmd_enabled |
false |
Allow CMD tests to run. When false, all CMD tests return NA. |
client.ps_enabled |
false |
Allow PowerShell tests to run (Windows only). When false, all PowerShell tests return NA. |
CMD and PowerShell element security
Enabling cmd_enabled or ps_enabled permits the agent to run shell/PowerShell commands as defined in your compliance tests. Only enable these if you trust the tests assigned to the agent and understand the security implications.
Heartbeat Interval Guidelines
The heartbeat setting controls how frequently the agent checks in with the server.
| Environment | Recommended | Reason |
|---|---|---|
| High-security | 60–120s |
Faster detection of policy changes |
| Standard | 300s |
Good balance of responsiveness and load |
| Large fleets (1000+) | 600s+ |
Reduces server load |
Tip
A random jitter of 0–9 seconds is automatically added to each heartbeat interval to prevent thundering herd problems in large deployments.
Key Management
Identity Loss
If the files in the keys directory are deleted, the agent loses its identity. It will automatically trigger a new ID 0 registration and require an administrator to re-approve the system in the dashboard.
Key Backup
Back up your server key files regularly, together with the database.
If they are lost, agents from 0.10.4 on refuse the server's replies until
scmclient --reset-server-key is run on each host (see below).
Server key pinning
Since 0.10.4 the agent pins the server's signing key the first time it registers, and from then on acts only on replies signed with it. A reply signed with any other key is refused and logged; the agent never gives up the pinned key because of what arrives over the network. This is what stops someone on the network between agent and server from sending the agent commands or upgrades.
The pinned key changes in two ways only:
- Key rotation. Under Settings → Danger Zone, Rotate Signing Key issues a new key. The previous key keeps working for 30 days, and replies signed with it tell the agent the new key; the agent switches at its next check-in. The Danger Zone shows how many agents have switched.
-
By hand, on the host. After the server is reinstalled, its key file is lost, or an agent was off for the whole 30 days:
The agent forgets the pinned key, and its next check-in pins the key the server presents. It can run while the agent service is running.
Agents also download upgrades only from their own server, and never to an older version than the one they run.
Clocks and replayed messages
Since 0.11.0 every message from an agent carries the time it was sent, and the server accepts it only if it is within 5 minutes of the server's own clock and newer than the last message it accepted from that agent. Each reply also carries a random value from the request it answers. Together these stop a recorded message, in either direction, from being played back later.
Keep the clocks of the server and the hosts in sync (NTP). An agent whose clock is more than 5 minutes off is refused, and its log says so:
Server returned error status 401 Unauthorized: Request timestamp is more than 5 minutes from the server's clock. Check the clock on this host (NTP).
Agents older than 0.11.0 keep working without these checks, and are marked legacy protocol in the Systems list until they are upgraded.
Keys are generated automatically on first run — no manual setup required.
Applying Changes
Configuration changes take effect on service restart.