Files
punktfunk/scripts/windows/scripting-run.cmd
T
enricobuehler 84c47cd0a7 feat(security): run the Windows plugin runner as LocalService, not SYSTEM
The PunktfunkScripting scheduled task ran operator-installed plugin code
as SYSTEM with -RunLevel Highest — any plugin defect was a full
compromise of the box. The principal is now NT AUTHORITY\LocalService
(minimal privileges, no password to manage, exists at boot, loopback
networking works), registered without RunLevel:

- installer: New-ScheduledTaskPrincipal -UserId 'LocalService'
- plugins enable: converges the principal idempotently (migrating tasks
  an older installer or a dev box registered as SYSTEM) BEFORE starting,
  then grants LocalService read — via icacls, full-System32-path — on
  exactly the two SYSTEM/Admins-DACL'd files the runner's connect()
  needs: the scoped plugin-token and the TLS-pin cert.pem. Never
  mgmt-token. plugins disable revokes the grants; plugins status now
  prints the task principal so the migration is verifiable.
- build-scripting.ps1 mirrors the convergence + grants on dev deploys.

The usage text also mentions the new --allow-public-registry gate that
lands with the supply-chain commit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 00:45:27 +02:00

30 lines
1.3 KiB
Batchfile

@echo off
rem punktfunk plugin/script runner launcher - the action the PunktfunkScripting scheduled task runs.
rem
rem OPT-IN: the installer registers that task DISABLED (the runner is inert until you add automation).
rem Enable it once you have scripts/plugins: Enable-ScheduledTask -TaskName PunktfunkScripting
rem
rem Lays out next to the installed payload: {app}\scripting\scripting-run.cmd + runner-cli.js and
rem {app}\bun\bun.exe (so %~dp0 = {app}\scripting\). The runner discovers the operator's units under
rem %ProgramData%\punktfunk\{scripts,plugins}; a plugin's connect() auto-wires to the host's SCOPED
rem plugin-token + identity cert in %ProgramData%\punktfunk\ (written by the host's `serve`). The
rem task runs as NT AUTHORITY\LocalService - `plugins enable` grants it read on exactly those two
rem files. No env editing.
setlocal EnableExtensions
set "BUN=%~dp0..\bun\bun.exe"
set "RUNNER=%~dp0runner-cli.js"
if not exist "%RUNNER%" (
echo [punktfunk-scripting] runner bundle missing at "%RUNNER%".
exit /b 1
)
if not exist "%BUN%" (
echo [punktfunk-scripting] bundled bun missing at "%BUN%".
exit /b 1
)
rem The runner import()s the operator's .ts plugin files, so it runs on the bundled bun. SIGTERM (task
rem End) interrupts the whole unit tree structurally so plugin finalizers run before exit.
"%BUN%" "%RUNNER%"