CoursesSaltAdvanced

Securing the Salt infrastructure

Key acceptance, the master, ACLs.

Advanced14 min · lesson 12 of 12

Salt’s trust model is minion key acceptance: a minion generates a key, the master must accept it before that minion receives commands or pillar. This is the front gate — accept the wrong key and you have handed an attacker a foothold that receives your states and secrets. Manage keys deliberately with salt-key: review pending requests, accept known minions, and reject or delete anything unexpected.

terminal
$ salt-key -L # list accepted / unaccepted / rejected keys
Unaccepted Keys:
web3.acme.internal
$ salt-key -a web3.acme.internal # accept a known minion deliberately
$ salt-key -d rogue-host # delete an unexpected one

Harden the master and scope access

The master can run functions as root on every minion, so it is the highest-value asset: patch it promptly (Salt masters have been targeted by serious CVEs), restrict network access to it, and never auto-accept keys in production. Scope who can run what with the master’s ACL system (client_acl / publisher_acl and external auth) so an operator or a CI user can run only specific functions on specific targets — not arbitrary cmd.run everywhere.

/etc/salt/master
auto_accept: False # never blindly accept minion keys in prod
publisher_acl:
ci-deploy: # this user may run only these, only on web*
- 'web*':
- state.apply
- service.restart
# plus external_auth (eauth) to tie ACLs to real identities (PAM/LDAP)
Patch the master and never auto-accept keys
Two failure modes cause most Salt incidents: an unpatched master (remote-code-execution CVEs have led to mass minion compromise) and auto_accept letting rogue minions join. Keep the master current on a short clock, set auto_accept: False and vet keys, restrict network reachability to the master, and use publisher_acl + eauth so no one has an unrestricted fleet-wide root shell.