[Unit] Description=Vetting orchestrator (post-repair hardware validation) Documentation=https://github.com/your-org/vetting After=network-online.target Wants=network-online.target [Service] Type=simple User=vetting Group=vetting ExecStart=/usr/local/bin/vetting --config /etc/vetting/vetting.yaml # The orchestrator embeds dnsmasq and sends raw WoL broadcasts. Rather # than run as root, grant just the caps we need: # CAP_NET_BIND_SERVICE — if the operator binds :443 or :80 # CAP_NET_RAW — WoL magic packet via DGRAM broadcast; not # strictly required when using UDP broadcast to # 255.255.255.255 on port 9, but safer to carry # so custom ports work. # CAP_NET_ADMIN — dnsmasq needs this to create the DHCP socket # and to bind to a specific interface. AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_NET_ADMIN CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_NET_RAW CAP_NET_ADMIN # Filesystem: the orchestrator needs to write to /var/lib/vetting and # /var/log/vetting. Everything else is read-only. ReadWritePaths=/var/lib/vetting /var/log/vetting ProtectSystem=strict ProtectHome=true NoNewPrivileges=true PrivateTmp=true PrivateDevices=true ProtectControlGroups=true ProtectKernelTunables=true ProtectKernelModules=true RestrictSUIDSGID=true RestrictNamespaces=true LockPersonality=true # Restart policy — crash out loudly on startup errors, but recover from # transient failures. Restart=on-failure RestartSec=5 StartLimitBurst=5 StartLimitIntervalSec=60 # Logs go to journald; the orchestrator's own per-run log files live # under /var/log/vetting regardless. StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target