fix(runners): register CLI and UI runners as active by default#3926
fix(runners): register CLI and UI runners as active by default#3926cursor[bot] wants to merge 1 commit into
Conversation
The --enabled flag on runner register defaults to true but was only applied when explicitly passed, leaving util.Config.Runner.Enabled false and creating inactive runners that never receive tasks. Also set Enabled=true for runner start --register and default new UI runners to active: true. Co-authored-by: Denis Gukov <fiftin@outlook.com>
There was a problem hiding this comment.
Security review
Outcome: No medium, high, or critical vulnerabilities found.
Reviewed the added/modified paths in this PR (cli/cmd/runner_register.go, cli/cmd/runner_start.go, web/src/components/RunnerForm.vue) and traced each change to its sinks and authorization boundaries.
Summary
This PR fixes a functional bug where new runners were created inactive despite the intended default of active. The changes align client defaults with existing server behavior and do not introduce a new attacker-controlled path.
| Change | Security assessment |
|---|---|
Always apply --enabled in applyRunnerRegisterFlags |
Local CLI flag only; --enabled=false still honored. Registration still requires a valid registration token at /api/internal/runners. |
Force Enabled=true in runner start --register |
Only runs when no auth token exists (first-time registration). The registration API already accepts client-supplied enabled; this does not bypass token checks. |
Default active: true in RunnerForm.getNewItem() |
UI creation remains behind admin auth (adminMiddleware) or CanManageProjectResources. Users with those permissions can already set active via the checkbox or /active endpoint. |
Prior threads
No previous automation security-review threads were found on this PR.
Slack summary
PR #3926 (runner active-by-default fix): Clean — no security findings. Changes restore intended runner activation defaults; existing registration-token and permission controls remain in place.
Sent by Cursor Automation: Find vulnerabilities
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 34c3c26769
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Always apply enabled: the flag defaults to true, but util.Config.Runner.Enabled | ||
| // stays false (zero value) unless we copy it. Without this, registration creates | ||
| // an inactive runner that never receives tasks. | ||
| util.Config.Runner.Enabled = runnerRegisterArgs.enabled |
There was a problem hiding this comment.
Preserve runner.enabled from config/env
When --enabled is omitted, this unconditional assignment overwrites any value loaded by ConfigInit from runner.enabled or SEMAPHORE_RUNNER_ENABLED; for example, a runner configured with SEMAPHORE_RUNNER_ENABLED=false will still be registered as active because Cobra initialized runnerRegisterArgs.enabled to the flag default true. This removes the existing config/env control for creating an inactive runner unless the operator also passes --enabled=false on this invocation; the same pattern is also introduced for runner start --register in runner_start.go.
Useful? React with 👍 / 👎.


Bug and impact
Runner registration via CLI (
semaphore runner registerorrunner start --register) and the UI "New Runner" form created inactive runners even when users expected them to be enabled. Inactive runners authenticate and poll successfully but are excluded from task dispatch (active=true and token != ''), so remote tasks fail with no available runners.Root cause
Commit dcc95c0 added the
--enabledflag (defaulttrue) butapplyRunnerRegisterFlagsonly copied it toutil.Config.Runner.Enabledwhen the flag was explicitly changed. The config struct zero value isfalse, so registration sentenabled: falseto the API.The UI
RunnerForm.getNewItem()also omittedactive: true, so new runners were saved withactive: false.Fix
runnerRegisterArgs.enabledinapplyRunnerRegisterFlags(respects--enabled=false)util.Config.Runner.Enabled = truebefore auto-registration inrunner start --registeractive: trueValidation
applyRunnerRegisterFlagsenabled behaviorgo test ./cli/cmd/... -run TestApplyRunnerRegisterFlagspasses