Self-hosted runners attached to a public repo are a known
severe-risk pattern: any workflow that gains the ability to run
PR-controlled code escalates to RCE on the runner host. Even
though this workflow is workflow_dispatch only today, the runner
itself sits one workflow edit away from arbitrary code execution
on whatever machine it's pinned to.
Changes:
- runs-on: self-hosted -> ubuntu-24.04. Reachability of base_url
from the GitHub-hosted runner is now the dispatcher's
responsibility. Add tailscale/* steps (like deploy-v6-preview-
demo.yml or deploy-demo-server.yml already do) if pointing at
a private Pulse instance.
- Drop the admin/admin fallback on PULSE_EVAL_USER and
PULSE_EVAL_PASS. The previous default was
${{ secrets.PULSE_EVAL_USER || 'admin' }} which silently ran
the eval as admin/admin if the secrets were missing. Added a
fail-closed precheck that refuses to proceed unless both
secrets are set.
- Route inputs.scenario, inputs.models, inputs.providers, and
inputs.base_url through env: indirection instead of inline
${{ }} interpolation into shell. Defense-in-depth against
script injection from the dispatch payload.
Net result: kills the audit's only CRITICAL finding and the
companion MEDIUM (admin/admin fallback). Eval can still run
exactly as before once secrets are set and base_url is reachable.