[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