Skip to content

[master] Isolate salt daemon writable state under /var/lib/salt/<daemon>/ (#70198) - #70199

Open
dwoz wants to merge 3 commits into
saltstack:masterfrom
dwoz:dwoz/feature/70198-onedir-harden-master
Open

[master] Isolate salt daemon writable state under /var/lib/salt/<daemon>/ (#70198)#70199
dwoz wants to merge 3 commits into
saltstack:masterfrom
dwoz:dwoz/feature/70198-onedir-harden-master

Conversation

@dwoz

@dwoz dwoz commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Ships the SALT_ONEDIR_HARDEN=1 default for 3009.0 (master). Per-daemon
writable state moves under /var/lib/salt/<daemon>/{home,extras-<py>}
so the /opt/saltstack/salt onedir tree stays root:root 0755.

What changes

  • DEB: salt-{common,minion,master,syndic,api,cloud}.{preinst,postinst}
    compute SALT_HOME / SALT_EXTRAS_DIR per-daemon under
    /var/lib/salt/<daemon>/ and chown only those (not the onedir tree)
    when SALT_ONEDIR_HARDEN=1 (default on 3009.0). Adds a new
    salt-cloud.preinst. salt-common.dirs gains /var/lib/salt.
  • RPM: pkg/rpm/salt.spec — same treatment in %pre,
    %post minion, %posttrans {master,syndic,api,cloud,minion}. Adds
    /var/lib/salt to %files.
  • Runtime: salt/scripts.py::salt_pip and
    pkg/common/onedir/_salt_onedir_extras.py honor SALT_EXTRAS_DIR
    so salt-pip install writes where the daemon's Python imports from.
  • Migration: %posttrans / DEB postinst move any populated
    /opt/saltstack/salt/extras-<py>/ into the per-daemon location
    once (idempotent no-op otherwise).
  • Opt-out: SALT_ONEDIR_HARDEN=0 in /etc/default/salt-setup
    (DEB) or /etc/sysconfig/salt-minion-setup (RPM) preserves the
    legacy chown, logs a logger -t salt-<daemon> deprecation notice,
    and is planned for removal after one release cycle.

Tests

  • tests/pytests/unit/test_scripts.py — 3 new tests for
    _resolve_extras_dir (fallback, env override, empty env).
  • tests/pytests/unit/test_salt_onedir_extras.py — 3 new tests for
    the .pth hook (fallback, env override, path promotion).
  • tests/pytests/pkg/integration/test_onedir_harden.py — new pkg
    integration coverage: /opt/saltstack/salt mode assertion,
    per-daemon dir ownership, salt-pip honors SALT_EXTRAS_DIR.

3006.x / 3007.x / 3008.x opt-in PRs are follow-ups on their own
branches, per the rollout in issue #70198.

Refs #70198.

…tstack#70198)

Default SALT_ONEDIR_HARDEN=1 on 3009.0+ so each daemon's writable
state lives under per-daemon /var/lib/salt/<daemon>/{home,extras-<py>}
directories and /opt/saltstack/salt stays root:root 0755. Set
SALT_ONEDIR_HARDEN=0 in /etc/default/salt-setup (DEB) or
/etc/sysconfig/salt-minion-setup (RPM) to restore the legacy
chown -R salt /opt/saltstack/salt behavior for one release; the
opt-out is deprecated and will be removed in a future release.

Runtime salt-pip and the onedir _salt_onedir_extras .pth hook honor
SALT_EXTRAS_DIR so packages installed via salt-pip continue to be
importable by the daemon after the packaging layer relocates the
extras tree. Postinst / posttrans scriptlets migrate any populated
legacy /opt/saltstack/salt/extras-<py>/ contents into the per-daemon
location once, idempotent no-op otherwise.
@dwoz
dwoz requested a review from a team as a code owner September 1, 2026 01:53
@dwoz dwoz added the test:full Run the full test suite label Sep 1, 2026
@dwoz dwoz added this to the Potassium v3009.0 milestone Sep 1, 2026
dwoz added 2 commits August 31, 2026 22:13
Adds per-daemon fanout for the writable-dir existence/ownership
checks (previously only master was covered), belt-and-braces asserts
for /opt/saltstack/salt files staying root-owned, an explicit
unset-vs-1 gate check, and multi-role isolation verification that
each daemon's /var/lib/salt/<daemon>/ is a distinct directory with
no cross-daemon file visibility. Collection grows from 3 to 20 tests.

Refs saltstack#70198.
New sibling directory tests/pytests/pkg/integration/onedir_harden_lifecycle/
covers what the session-scoped install_salt fixture can't:

- SALT_ONEDIR_HARDEN=0 opt-out: legacy /opt/saltstack/salt chown,
  deprecation warning surfaces via journalctl / syslog, per-daemon
  /var/lib/salt/<daemon>/ dirs absent
- SALT_ONEDIR_HARDEN unset == hardened default
- Explicit SALT_HOME and SALT_EXTRAS_DIR overrides win over the
  HARDEN=1 default (per-daemon dirs replaced by operator-chosen paths)
- Upgrade migration: pre-populates /opt/saltstack/salt/extras-<py>/
  with a marker under HARDEN=0, then reinstalls with HARDEN=1 and
  asserts marker moved into /var/lib/salt/<daemon>/extras-<py>/
- Idempotency: dpkg-reconfigure / dnf reinstall doesn't resurrect the
  legacy dir or duplicate the marker

Mirrors the config_overrides/ destructive-fixture pattern
(collection-skip on upgrade/downgrade/no-install passes, per-test
apt/rpm purge, force-purge on postinst failure). 8 new tests.

Refs saltstack#70198.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test:full Run the full test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants