You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
request is for a least-privilege boundary for running specific mas install or update operations non-interactively.
The released 7.0 implementation and the privilege implementation currently on main expose different problems for restricted NOPASSWD configurations:
7.0 re-executes mas through sudo with an internal environment assignment, which requires an additional sudoers environment exception.
Current main now invokes privileged system tools directly. That removes the environment-assignment failure, but an exact rule authorizing the requested mas command no longer authorizes the commands that mas passes to sudo.
The default interactive behavior can remain unchanged. This request is for a supported interface for automation that deliberately grants only a specific MAS operation, rather than broad passwordless root access.
Observed behavior in 7.0
I use an exact rule shaped like this for a declared application:
However, that makes the external privilege policy depend on an internal mas optimization and does not address the privilege boundary used by current main.
Remaining gap on current main
The privilege-handling changes merged for the 7.1 release (as it currently stands from what I see) no longer re-execute the MAS binary as root.
Based on that merged code, the exact NOPASSWD rule for <mas-path> update --force 803453959 cannot match these child sudo commands.
A policy would instead need to authorize installer with dynamic package paths and a root shell command with dynamic receipt paths. Such rules are broader, more brittle across MAS releases, and no longer express the intended policy:
"allow MAS to update this app ID."
This also leaves the restricted rule suggested in the discussion of #1095 without an equivalent supported shape for the new privilege model:
This matters for brew bundle, declarative workstation configuration, and other unattended update workflows. Homebrew itself cannot safely be run as root, while granting broad passwordless access to generic system tools defeats the purpose of using an app-specific sudoers rule.
Proposed solution(s)
a supported way to authorize a specific MAS operation and app ID without requiring any of the following:
SETENV or a global environment exception;
broad passwordless access to /usr/sbin/installer;
passwordless access to /bin/sh with dynamic arguments;
running Homebrew or the entire caller as root; or
policies coupled to MAS temporary paths and internal subprocesses.
For example, MAS could expose a root-owned privileged helper whose stable command line contains the requested operation and app IDs. The helper could validate and manage installer packages and receipts internally. A restricted policy could then remain shaped like:
Problem(s) addressed
request is for a least-privilege boundary for running specific
masinstall or update operations non-interactively.The released 7.0 implementation and the privilege implementation currently on
mainexpose different problems for restrictedNOPASSWDconfigurations:masthroughsudowith an internal environment assignment, which requires an additionalsudoersenvironment exception.mainnow invokes privileged system tools directly. That removes the environment-assignment failure, but an exact rule authorizing the requestedmascommand no longer authorizes the commands thatmaspasses tosudo.The default interactive behavior can remain unchanged. This request is for a supported interface for automation that deliberately grants only a specific MAS operation, rather than broad passwordless root access.
Observed behavior in 7.0
I use an exact rule shaped like this for a declared application:
When an update requires elevation, MAS 7.0 actually executes the equivalent of:
$ sudo MAS_NO_AUTO_INDEX=1 <mas-path> update --force 803453959sudotherefore rejects the internal environment assignment even though the mas command itself is authorized:This comes from the 7.0 elevation implementation:
https://github.com/mas-cli/mas/blob/v7.0.0/Sources/mas/Utilities/Processes/Sudo.swift#L20-L29
A command-specific workaround is possible:
However, that makes the external privilege policy depend on an internal mas optimization and does not address the privilege boundary used by current
main.Remaining gap on current
mainThe privilege-handling changes merged for the 7.1 release (as it currently stands from what I see) no longer re-execute the MAS binary as root.
Relevant code:
mas/Sources/mas/Models/AppStoreAction.swift
Lines 290 to 340 in 1eeacfc
Based on that merged code, the exact
NOPASSWDrule for<mas-path> update --force 803453959cannot match these childsudocommands.A policy would instead need to authorize
installerwith dynamic package paths and a root shell command with dynamic receipt paths. Such rules are broader, more brittle across MAS releases, and no longer express the intended policy:"allow MAS to update this app ID."
This also leaves the restricted rule suggested in the discussion of #1095 without an equivalent supported shape for the new privilege model:
#1095 (comment)
Motivation
This matters for
brew bundle, declarative workstation configuration, and other unattended update workflows. Homebrew itself cannot safely be run as root, while granting broad passwordless access to generic system tools defeats the purpose of using an app-specificsudoersrule.Proposed solution(s)
a supported way to authorize a specific MAS operation and app ID without requiring any of the following:
SETENVor a global environment exception;/usr/sbin/installer;/bin/shwith dynamic arguments;For example, MAS could expose a root-owned privileged helper whose stable command line contains the requested operation and app IDs. The helper could validate and manage installer packages and receipts internally. A restricted policy could then remain shaped like:
Related