Skip to content

[3008.x] Add whitelist_state_modules minion option - #70193

Open
dwoz wants to merge 1 commit into
saltstack:3008.xfrom
dwoz:dwoz/feat/whitelist-state-modules
Open

[3008.x] Add whitelist_state_modules minion option#70193
dwoz wants to merge 1 commit into
saltstack:3008.xfrom
dwoz:dwoz/feat/whitelist-state-modules

Conversation

@dwoz

@dwoz dwoz commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds a new whitelist_state_modules minion option that restricts which state modules the state loader will load, complementing:

  • whitelist_modules — gates execution modules on the wire
  • renderer_whitelist — gates renderers

Motivation

whitelist_modules prevents wire callers from invoking non-permitted execution modules (salt <tgt> cmd.run 'id' is denied), but an SLS author with write access to the state tree can still write:

run_shell:
  cmd.run:                # <-- STATE module named cmd, function run
    - name: id

…and state.apply executes it unconditionally. For VCF-style hardening the operator needs a symmetric control over which state modules are loadable.

Design (minimal — single feature)

  • New opt whitelist_state_modules: [test, file, pkg, service, ...] in minion config. Case-sensitive module-name (not function-name) allowlist. Unset / empty list = no filtering (backward compat).
  • salt.loader.states now reads the opt when the caller doesn't pass an explicit whitelist= kwarg, mirroring salt.loader.minion_mods's pattern for whitelist_modules.
  • The value flows through to the underlying LazyLoader as whitelist= unchanged; LazyLoader._load already enforces the gate.
  • SLS referencing a non-whitelisted state module fails per-chunk with {"result": False, "comment": "Specified state '...' was not found", "changes": {}} — no silent execution.
  • whitelist_modules and whitelist_state_modules are strictly orthogonal.

Diff scope

File Change
salt/loader/__init__.py states() reads opts["whitelist_state_modules"] when whitelist not passed.
salt/config/__init__.py New whitelist_state_modules: list type entry + [] default in DEFAULT_MINION_OPTS.
conf/minion New commented-out example directly below whitelist_modules.
changelog/vcops-90587-state-whitelist.added.md One-line changelog (rename to <PR#>.added.md after review).

Total: ~30 lines of code + docs, 4 tests.

Test coverage (three tiers, no unit-only)

Tier File Tests
Unit tests/pytests/unit/loader/test_state_whitelist.py 4
Functional tests/pytests/functional/loader/test_state_whitelist.py 8
Integration tests/pytests/integration/states/test_whitelist.py 4

The integration tier boots a real salt-master + salt-minion pair, dispatches state.apply from the wire, and verifies both the allow path and the deny path — including a canary-file check to prove the non-whitelisted cmd.run state does NOT silently execute.

Merge requirements satisfied?

  • Docs — commented example in conf/minion, docstring update on salt.loader.states.
  • Changelog — changelog/vcops-90587-state-whitelist.added.md (rename to <PR#>.added.md after review).
  • Tests written — unit + functional + integration, 16 new.

Commits signed with GPG?

No — DCO sign-off only (Signed-off-by: trailer).

Relation to PR #70192

Independent of PR #70192 (whitelist_modules two-loader completion). This PR is strictly additive; the two overlap on salt.loader.states()'s function signature and can be rebased if #70192 merges first.

@dwoz
dwoz requested a review from a team as a code owner August 30, 2026 22:21
@dwoz
dwoz force-pushed the dwoz/feat/whitelist-state-modules branch from e172fad to 20b4fe7 Compare August 30, 2026 22:21
@dwoz dwoz added the test:full Run the full test suite label Aug 30, 2026
@twangboy twangboy added this to the Argon v3008.3 milestone Aug 31, 2026
twangboy
twangboy previously approved these changes Aug 31, 2026
Signed-off-by: Daniel A. Wozniak <daniel.wozniak@broadcom.com>
@dwoz
dwoz force-pushed the dwoz/feat/whitelist-state-modules branch from c04c780 to f41f504 Compare September 1, 2026 09:24
@dwoz

dwoz commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Rebase left a stray blank line in salt/loader/__init__.py:1205 that Pre-Commit (black) tripped on. Squashed the fix back into the single commit; force-pushed f41f504f8d4.

The remaining integration test failures on salt-ssh --relenv state.* variants are the same pre-existing Failed to spawn the VT. Error: [Errno 7] Argument list too long: '/usr/bin/ssh' ARG_MAX bug that hits every open PR — not caused by this change. Twangboy's #70194 is the fix.

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