[Unit]
Description=ifcurl render isolation service (IFC parsing + rendering)
Documentation=https://github.com/brunopostle/ifcurl
After=network.target

[Service]
Type=simple
User=ifcurl-render
Group=ifcurl-render
RuntimeDirectory=ifcurl
RuntimeDirectoryMode=0775
RuntimeDirectoryPreserve=yes
ExecStart=/opt/ifcurl/bin/ifcurl render-service \
    --socket /run/ifcurl/render.sock
Restart=on-failure
RestartSec=5

# Render configuration — override in /etc/ifcurl/render-env:
#   IFCURL_SANDBOX_TIMEOUT=120   max seconds per render subprocess
#   IFCURL_SANDBOX_MEMORY_MB=0   address-space cap per subprocess (0=unlimited)

# ---------------------------------------------------------------------------
# Sandbox hardening
#
# This service processes untrusted IFC data via ifcopenshell and pyvista.
# It has no credentials, no git access, and no outbound network.
#
# AF_UNIX only: the service receives requests from ifcurl-api over the
# render socket and communicates with its own sandbox child processes.
# AF_INET/AF_INET6 are excluded — a compromised subprocess cannot reach
# git hosts or any other external service.
#
# ProtectSystem=strict + no ReadWritePaths: this service writes nothing to
# disk; all output is returned over the Unix socket to the API service.
# ---------------------------------------------------------------------------
EnvironmentFile=-/etc/ifcurl/render-env
Environment=MPLCONFIGDIR=/var/cache/ifcurl-render
CacheDirectory=ifcurl-render
NoNewPrivileges=yes
RestrictSUIDSGID=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
RestrictNamespaces=yes
LockPersonality=yes
RestrictRealtime=yes
RestrictAddressFamilies=AF_UNIX
SystemCallArchitectures=native
SystemCallFilter=@system-service @process @files @io-event
SystemCallErrorNumber=EPERM

[Install]
WantedBy=multi-user.target
