Summary
On shared-web project VMs, the deploy/app user (the account samohost SSHes in as to build, deploy, and manage apps) is granted a root-equivalent catch-all sudo rule — effectively <deploy-user> ALL=(ALL) NOPASSWD:ALL — via a cloud-init-generated sudoers drop-in. This catch-all silently overrides and nullifies the fine-grained, per-command sudoers rules that samohost's own provisioning (buildHostPrepScript / bootstrap) carefully emits for the env/deploy paths.
Net effect: those least-privilege grants become security theater. They enumerate exactly which commands the deploy user should be allowed to run as root, but because a broader NOPASSWD:ALL rule already covers everything, the enumeration constrains nothing. The deploy user can run any command as root regardless of what the fine-grained files say.
Why this is a real problem (not just cosmetic)
-
Blast radius. A compromise (or a bug) in any deploy-time command runs as root on the VM, defeating the entire point of scoping the deploy user's privileges. The hardening story ("deploy runs least-privilege") is false in effective posture.
-
It masks real coverage gaps. Because everything "just works" under the catch-all, missing entries in the fine-grained sudoers go undetected. Concretely, during recent shared-web preview work a sudo -u ... tee step that writes an app config file appeared to work — but it only worked because of the catch-all. On a properly-hardened VM (deploy user scoped to just the enumerated commands) that step would have been denied. So the catch-all is actively hiding places where the real sudoers is incomplete, and those gaps will surface as failures the first time a VM is hardened correctly.
Recommendation
- Scope the deploy user's sudo to the specific commands samohost actually needs — the env/deploy sudoers samohost already emits enumerate them, so the allowed set is already known.
- Drop the cloud-init
NOPASSWD:ALL catch-all on project VMs (and retrofit existing ones).
- Add an audit/
doctor check that fails when the deploy user has a broad NOPASSWD:ALL (or otherwise root-equivalent) grant, so a re-introduced catch-all is caught rather than silently trusted.
- Once the catch-all is gone, re-run the deploy/preview flows to surface (and fill) any fine-grained sudoers gaps that the catch-all was masking (e.g. the config-file
tee step above).
Then the least-privilege grants samohost emits are real, and the "deploy runs least-privilege" claim actually holds.
Notes
Summary
On shared-web project VMs, the deploy/app user (the account samohost SSHes in as to build, deploy, and manage apps) is granted a root-equivalent catch-all sudo rule — effectively
<deploy-user> ALL=(ALL) NOPASSWD:ALL— via a cloud-init-generated sudoers drop-in. This catch-all silently overrides and nullifies the fine-grained, per-command sudoers rules that samohost's own provisioning (buildHostPrepScript/ bootstrap) carefully emits for the env/deploy paths.Net effect: those least-privilege grants become security theater. They enumerate exactly which commands the deploy user should be allowed to run as root, but because a broader
NOPASSWD:ALLrule already covers everything, the enumeration constrains nothing. The deploy user can run any command as root regardless of what the fine-grained files say.Why this is a real problem (not just cosmetic)
Blast radius. A compromise (or a bug) in any deploy-time command runs as root on the VM, defeating the entire point of scoping the deploy user's privileges. The hardening story ("deploy runs least-privilege") is false in effective posture.
It masks real coverage gaps. Because everything "just works" under the catch-all, missing entries in the fine-grained sudoers go undetected. Concretely, during recent shared-web preview work a
sudo -u ... teestep that writes an app config file appeared to work — but it only worked because of the catch-all. On a properly-hardened VM (deploy user scoped to just the enumerated commands) that step would have been denied. So the catch-all is actively hiding places where the real sudoers is incomplete, and those gaps will surface as failures the first time a VM is hardened correctly.Recommendation
NOPASSWD:ALLcatch-all on project VMs (and retrofit existing ones).doctorcheck that fails when the deploy user has a broadNOPASSWD:ALL(or otherwise root-equivalent) grant, so a re-introduced catch-all is caught rather than silently trusted.teestep above).Then the least-privilege grants samohost emits are real, and the "deploy runs least-privilege" claim actually holds.
Notes