Optional unrooting st2actionrunner and st2workflowengine - #6403
Open
guzzijones wants to merge 4 commits into
Open
Optional unrooting st2actionrunner and st2workflowengine#6403guzzijones wants to merge 4 commits into
guzzijones wants to merge 4 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Optional unrooting of
st2actionrunnerandst2workflowenginewith a configurable security mode(by @guzzijones12@gmail.com).
What changed. The
st2actionrunner@andst2workflowenginesystemd units now run as theunprivileged
st2user (groupst2packs) instead ofroot. The non-templatedst2actionrunner.serviceremains arootoneshotbecause it only callssystemctl start/stop st2actionrunner@N(viarunners.sh); it executes no action code. A new[system_security]config section is added with two options:security_mode(legacyorrestricted, defaultlegacy) andallowed_run_as_users(defaultstanley,root).Does not break consensus / backward compatible. The default is
legacy, which preserves thehistorical behavior: broad
NOPASSWD: ALLsudo for thest2user (tostanleyandroot).Existing installs and packs continue to work unchanged after upgrade. Unrooting and the tighter
restrictedmode are strictly opt-in, so this is not a breaking consensus change -- operators whowant the hardening choose it, everyone else keeps today's behavior.
Two enforcement layers (they are NOT redundant).
Application-level pre-check --
local_runnerreadscfg.CONF.system_securityat runtime onevery action. In
restrictedmode it rejects a target user not inallowed_run_as_usersand ascript
entry_pointoutsidebase_path. This is enforced inside thest2process, so it is afirst-line convenience/early-failure guard with helpful errors -- NOT a boundary against a
compromised or buggy runner, and it does not path-restrict arbitrary local commands (
cmd=...).OS-level sudoers --
/etc/sudoers.d/st2is the real security boundary, enforced bysudo(setuid-root), and it holds even if the
st2process is compromised. It does two things the appcheck cannot: (a) it grants the privilege in the first place -- once unrooted, the unprivileged
st2user can onlysudotostanley/rootbecause this file allows it, so the file isrequired for local
sudo/run-as-user actions to work at all; and (b) inrestrictedmode it isthe hard ceiling -- sudo execution is scoped to commands under
/opt/stackstormand dangerouscommands (
passwd,su,visudo,sudo) are denied, so a tricked runner still cannotsudoarbitrary binaries as root.How the sudoers file is generated. A new
st2-setup-sudoscript (packaged into/opt/stackstorm/st2/bin) readssecurity_modefromst2.confand writes/etc/sudoers.d/st2accordingly, validating it with
visudo -c(and removing the file on syntax error). It is invoked bythe package post-install as
root.How to enable restricted mode.
Set
allowed_run_as_usersto the exact set of users your actions actually run as. For mostdeployments this is just the default system user,
stanley. Keeprootin the list only if yougenuinely have actions that run as
root; dropping it tightens the surface. Example::Ensure any local script actions live under
/opt/stackstorm(packs already install there), sincerestrictedmode only permits sudo execution of commands under that path. Actions that callexternal scripts outside
/opt/stackstormmust be moved into a pack or will be rejected.Regenerate the sudoers file as
rootso the OS-level boundary matches the new mode::Restart the st2 services (e.g.
sudo st2ctl restart) and exercise a representative action. If anaction fails with a "Security violation" error, add the missing user to
allowed_run_as_usersormove the script under
/opt/stackstorm-- do not fall back tolegacyunless you must.A safe transition path is: upgrade on
legacy(no behavior change), then flip a single node torestricted, validate your packs, and roll it out.Containers/Kubernetes. Because the sudoers file is generated at package post-install (image-build)
time, a container image that wants
restrictedmode must be built with anst2.confthat alreadysets
security_mode = restricted(sost2-setup-sudowrites the scoped sudoers into the image).