Skip to main content
Cerbos can be deployed as a systemd service for production Linux environments, providing automatic startup, restart on failure, and system integration.

Prerequisites

  • Linux system with systemd (systemd version 232 or higher recommended)
  • Cerbos binary installed
  • Root or sudo access for service installation

Installation

1
Download Cerbos binary
2
# Download latest release
curl -L https://github.com/cerbos/cerbos/releases/latest/download/cerbos_Linux_x86_64.tar.gz | \
  sudo tar xz -C /usr/local/bin cerbos

# Make executable
sudo chmod +x /usr/local/bin/cerbos

# Verify installation
cerbos version
3
Create configuration directory
4
sudo mkdir -p /etc/cerbos
sudo mkdir -p /var/cerbos/policies
5
Create configuration file
6
Create /etc/cerbos.yaml:
7
---
server:
  httpListenAddr: ":3592"
  grpcListenAddr: ":3593"

engine:
  defaultPolicyVersion: "default"

storage:
  driver: "disk"
  disk:
    directory: /var/cerbos/policies
    watchForChanges: true
8
Install systemd service
9
Create /etc/systemd/system/cerbos.service:
10
[Unit]
Description=Cerbos Policy Decision Point
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/cerbos server --config=/etc/cerbos.yaml
Restart=on-failure
RestartSec=5s

# Security hardening
ProtectSystem=full
ProtectHome=true
PrivateUsers=true
PrivateTmp=true
DynamicUser=yes

# Working directory
WorkingDirectory=/var/cerbos

# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=cerbos

[Install]
WantedBy=multi-user.target
11
Reload systemd and start service
12
sudo systemctl daemon-reload
sudo systemctl enable cerbos
sudo systemctl start cerbos
13
Verify service status
14
sudo systemctl status cerbos

Service Management

Basic Commands

sudo systemctl start cerbos

View Logs

sudo journalctl -u cerbos -n 100

Configuration

Server Configuration

The default configuration file at /etc/cerbos.yaml:
server:
  httpListenAddr: ":3592"
  grpcListenAddr: ":3593"
  
  # Optional: Enable TLS
  tls:
    cert: /etc/cerbos/tls/server.crt
    key: /etc/cerbos/tls/server.key
    caCert: /etc/cerbos/tls/ca.crt
  
  # Optional: Request limits
  requestLimits:
    maxActionsPerResource: 50
    maxResourcesPerRequest: 50

engine:
  defaultPolicyVersion: "default"

storage:
  driver: "disk"
  disk:
    directory: /var/cerbos/policies
    watchForChanges: true

Storage Backends

storage:
  driver: "disk"
  disk:
    directory: /var/cerbos/policies
    watchForChanges: true

Environment Variables

Add environment variables to the service:
[Service]
Environment="CERBOS_LOG_LEVEL=info"
Environment="GITHUB_TOKEN=ghp_xxxxxxxxxxxx"
EnvironmentFile=/etc/cerbos/environment
Create /etc/cerbos/environment:
CERBOS_LOG_LEVEL=info
CERBOS_HUB_CLIENT_ID=client_id
CERBOS_HUB_CLIENT_SECRET=client_secret
CERBOS_HUB_DEPLOYMENT_ID=deployment_id
Ensure environment files with secrets have restricted permissions:
sudo chmod 600 /etc/cerbos/environment

Security Hardening

Enhanced Service Configuration

A production-hardened systemd service:
[Unit]
Description=Cerbos Policy Decision Point
Documentation=https://docs.cerbos.dev
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/cerbos server --config=/etc/cerbos.yaml
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
KillMode=process
KillSignal=SIGTERM
TimeoutStopSec=30

# User and group
User=cerbos
Group=cerbos

# Working directory
WorkingDirectory=/var/cerbos

# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=cerbos

# Security hardening
NoNewPrivileges=true
PrivateTmp=true
PrivateDevices=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/cerbos
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictRealtime=true
RestrictSUIDSGID=true
LockPersonality=true
MemoryDenyWriteExecute=true
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native

# Resource limits
LimitNOFILE=65535
LimitNPROC=512

[Install]
WantedBy=multi-user.target

Create Dedicated User

# Create system user
sudo useradd -r -s /bin/false -d /var/cerbos -c "Cerbos Service User" cerbos

# Set ownership
sudo chown -R cerbos:cerbos /var/cerbos
sudo chown -R cerbos:cerbos /etc/cerbos
Update the service file to use the dedicated user:
[Service]
User=cerbos
Group=cerbos
DynamicUser=no

File Permissions

# Configuration files
sudo chmod 644 /etc/cerbos.yaml
sudo chmod 600 /etc/cerbos/environment

# Policy directory
sudo chmod 755 /var/cerbos/policies
sudo chmod 644 /var/cerbos/policies/*.yaml

# TLS certificates
sudo chmod 600 /etc/cerbos/tls/*.key
sudo chmod 644 /etc/cerbos/tls/*.crt

Health Checks

Manual Health Check

curl http://localhost:3592/_cerbos/health
Expected response:
{"status":"SERVING"}

Systemd Health Check

Add a health check to the service:
[Service]
ExecStartPost=/bin/sh -c 'until curl -sf http://localhost:3592/_cerbos/health; do sleep 1; done'

External Monitoring

Create a separate systemd timer for health checks: /etc/systemd/system/cerbos-health.service:
[Unit]
Description=Cerbos Health Check

[Service]
Type=oneshot
ExecStart=/usr/local/bin/cerbos-health-check.sh
/etc/systemd/system/cerbos-health.timer:
[Unit]
Description=Cerbos Health Check Timer

[Timer]
OnBootSec=5min
OnUnitActiveSec=5min

[Install]
WantedBy=timers.target

TLS Configuration

1
Generate TLS certificates
2
sudo mkdir -p /etc/cerbos/tls

# Generate CA key and certificate
openssl genrsa -out /etc/cerbos/tls/ca.key 4096
openssl req -new -x509 -days 365 -key /etc/cerbos/tls/ca.key \
  -out /etc/cerbos/tls/ca.crt

# Generate server key and certificate
openssl genrsa -out /etc/cerbos/tls/server.key 4096
openssl req -new -key /etc/cerbos/tls/server.key \
  -out /etc/cerbos/tls/server.csr
openssl x509 -req -days 365 -in /etc/cerbos/tls/server.csr \
  -CA /etc/cerbos/tls/ca.crt -CAkey /etc/cerbos/tls/ca.key \
  -CAcreateserial -out /etc/cerbos/tls/server.crt
3
Update configuration
4
Edit /etc/cerbos.yaml:
5
server:
  httpListenAddr: ":3592"
  grpcListenAddr: ":3593"
  tls:
    cert: /etc/cerbos/tls/server.crt
    key: /etc/cerbos/tls/server.key
    caCert: /etc/cerbos/tls/ca.crt
6
Restart service
7
sudo systemctl restart cerbos
8
Test TLS connection
9
curl --cacert /etc/cerbos/tls/ca.crt https://localhost:3592/_cerbos/health

Audit Logging

Enable audit logging to track all policy decisions:
audit:
  enabled: true
  backend: "file"
  file:
    path: /var/log/cerbos/audit.log
    retentionPeriod: 168h  # 7 days
Create log directory:
sudo mkdir -p /var/log/cerbos
sudo chown cerbos:cerbos /var/log/cerbos
Configure log rotation in /etc/logrotate.d/cerbos:
/var/log/cerbos/audit.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 cerbos cerbos
    postrotate
        systemctl reload cerbos
    endscript
}

Firewall Configuration

UFW (Ubuntu/Debian)

sudo ufw allow 3592/tcp comment 'Cerbos HTTP'
sudo ufw allow 3593/tcp comment 'Cerbos gRPC'
sudo ufw reload

firewalld (RHEL/CentOS)

sudo firewall-cmd --permanent --add-port=3592/tcp
sudo firewall-cmd --permanent --add-port=3593/tcp
sudo firewall-cmd --reload

Backup and Recovery

Backup Configuration

#!/bin/bash
# /usr/local/bin/backup-cerbos.sh

BACKUP_DIR="/backup/cerbos/$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"

# Backup configuration
cp -r /etc/cerbos.yaml "$BACKUP_DIR/"
cp -r /etc/cerbos/ "$BACKUP_DIR/config/"

# Backup policies
cp -r /var/cerbos/policies "$BACKUP_DIR/"

# Backup logs
cp -r /var/log/cerbos "$BACKUP_DIR/"

echo "Backup completed: $BACKUP_DIR"

Restore Configuration

# Stop service
sudo systemctl stop cerbos

# Restore files
sudo cp backup/cerbos.yaml /etc/cerbos.yaml
sudo cp -r backup/policies/* /var/cerbos/policies/

# Set permissions
sudo chown -R cerbos:cerbos /var/cerbos/policies

# Start service
sudo systemctl start cerbos

Troubleshooting

Service Won’t Start

# Check service status
sudo systemctl status cerbos

# View detailed logs
sudo journalctl -xeu cerbos

# Verify configuration
sudo cerbos validate /etc/cerbos.yaml

# Check binary
which cerbos
cerbos version

Permission Errors

# Check file ownership
ls -la /etc/cerbos.yaml
ls -la /var/cerbos/

# Fix permissions
sudo chown -R cerbos:cerbos /var/cerbos
sudo chmod 755 /var/cerbos

Port Already in Use

# Check what's using the port
sudo netstat -tlnp | grep 3592
sudo lsof -i :3592

# Change port in configuration
sudo nano /etc/cerbos.yaml

High Memory Usage

# Check memory usage
systemctl status cerbos

# Add memory limits to service
sudo systemctl edit cerbos
Add:
[Service]
MemoryMax=512M
MemoryHigh=384M

Complete Production Example

A complete production configuration: /etc/cerbos.yaml:
---
server:
  httpListenAddr: ":3592"
  grpcListenAddr: ":3593"
  tls:
    cert: /etc/cerbos/tls/server.crt
    key: /etc/cerbos/tls/server.key
    caCert: /etc/cerbos/tls/ca.crt
  requestLimits:
    maxActionsPerResource: 50
    maxResourcesPerRequest: 50

engine:
  defaultPolicyVersion: "default"

storage:
  driver: "git"
  git:
    protocol: https
    url: https://github.com/org/policies.git
    branch: production
    checkoutDir: /var/cerbos/work
    updatePollInterval: 60s
    https:
      username: ${GITHUB_TOKEN}
      password: ""

audit:
  enabled: true
  backend: "file"
  file:
    path: /var/log/cerbos/audit.log
    retentionPeriod: 168h

telemetry:
  enabled: true
  backend: "prometheus"
This provides a secure, production-ready Cerbos deployment as a systemd service.