From da682f10173ef315185bf0e93f86e2a79ae50c69 Mon Sep 17 00:00:00 2001 From: Jon Chery Date: Fri, 7 Aug 2026 11:29:26 +0000 Subject: [PATCH] =?UTF-8?q?fix(P19):=20sudoers=20hardening=20=E2=80=94=20r?= =?UTF-8?q?emove=20apt-get/dpkg=20(REQ-134,=20F22)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ---ci--- project: orca phase: 19 milestone: v0.12 status: execute ---/ci--- apt-get/dpkg removed from sudoers entirely (NOEXEC breaks maintainer scripts; operator runs apt-get/dpkg out-of-band). Only pct + qm remain (both NOEXEC). Tests updated. Build green. --- internal/proxmox/bootstrap.go | 6 +++--- internal/proxmox/bootstrap_test.go | 14 ++++---------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/internal/proxmox/bootstrap.go b/internal/proxmox/bootstrap.go index c564fe6..7e9f857 100644 --- a/internal/proxmox/bootstrap.go +++ b/internal/proxmox/bootstrap.go @@ -449,9 +449,9 @@ func sudoersContent(user string) string { # pvesh is EXCLUDED (AD-020: pvesh can bypass NOEXEC via API execute). %s ALL=(root) NOPASSWD: NOEXEC: /usr/bin/pct %s ALL=(root) NOPASSWD: NOEXEC: /usr/bin/qm -%s ALL=(root) NOPASSWD: NOEXEC: /usr/bin/apt-get -%s ALL=(root) NOPASSWD: NOEXEC: /usr/bin/dpkg -`, user, user, user, user) + + +`, user, user) } // writeSudoers writes the /etc/sudoers.d/orca file on the remote host diff --git a/internal/proxmox/bootstrap_test.go b/internal/proxmox/bootstrap_test.go index 73b10ae..8499ae1 100644 --- a/internal/proxmox/bootstrap_test.go +++ b/internal/proxmox/bootstrap_test.go @@ -33,17 +33,11 @@ func TestSudoersContent(t *testing.T) { t.Error("missing NOEXEC on qm (AD-020)") } - if !strings.Contains(content, "NOPASSWD: /usr/bin/apt-get") { - t.Error("missing NOPASSWD on apt-get") + if strings.Contains(content, "apt-get") { + t.Error("apt-get must NOT be in sudoers (REQ-134/F22: operator runs apt-get out-of-band)") } - if !strings.Contains(content, "NOPASSWD: /usr/bin/dpkg") { - t.Error("missing NOPASSWD on dpkg") - } - if strings.Contains(content, "NOEXEC: /usr/bin/apt-get") { - t.Error("apt-get must NOT have NOEXEC (breaks maintainer scripts)") - } - if strings.Contains(content, "NOEXEC: /usr/bin/dpkg") { - t.Error("dpkg must NOT have NOEXEC (breaks maintainer scripts)") + if strings.Contains(content, "dpkg") { + t.Error("dpkg must NOT be in sudoers (REQ-134/F22: operator runs dpkg out-of-band)") } for _, line := range strings.Split(content, "\n") {