puppet: reduce privilege in namespace workloads (#307) #319

Merged
benvin merged 1 commits from benvin/puppet-rootless into main 2026-08-08 22:36:44 +10:00
Owner

Why: shrink the blast radius of the Puppet control-plane pods (CA/eyaml keys, compiled catalogs) per the security sweep in #307 — remove root where it is not required and strip cargo-culted capabilities.

How:

  • puppetboard cert-generator init: root+APE:true -> uid 1000, drop:[all], APE:false; pod fsGroup 1000; removed trailing chown -R 1000:1000 (PVC now group-owned).
  • puppetdb create-log-dir init: root -> uid 999, drop:[all], APE:false; pod fsGroup 999; removed chown 999:999.
  • All OpenVox capability add-lists: removed the duplicate CAP_-prefixed spellings (k8s normalises both to the same kernel cap) and dropped the unused AUDIT_WRITE.
  • Added allowPrivilegeEscalation:false and seccompProfile RuntimeDefault across the workloads.

Stays root (evidence-backed, class-B fallback): the puppetserver master/compiler and puppetdb main containers, plus the perms-and-dirs and generate-types root containers. The OpenVox image entrypoint runs chown -R puppet:puppet over root-owned baked-in dirs and drops the JVM to the puppet user via runuser (needs CHOWN/SETUID/SETGID); a non-root start crashloops. Their cap sets are reduced to the minimum justified (CHOWN/DAC_OVERRIDE/FOWNER[/SETUID/SETGID]).

Validation: kustomize build --enable-helm clean; kubeconform 0 invalid / 0 errors; pre-commit (yamllint etc.) green. Confirmed against live pods: puppetserver/puppetdb JVMs already run as puppet/puppetdb via runuser; pam_loginuid is absent from the su/runuser PAM stacks and loginuid is unset, so dropping AUDIT_WRITE is safe.

Post-merge smoke test (puppet had an outage this session — watch closely): after argocd sync, confirm puppetserver master + a compiler reach running at /status/v1/simple, puppetdb reaches running, puppetboard serves 200, and the generate-types + g10k CronJobs complete — i.e. catalogs still compile and reports still ingest.

Closes #307

https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv

Why: shrink the blast radius of the Puppet control-plane pods (CA/eyaml keys, compiled catalogs) per the security sweep in #307 — remove root where it is not required and strip cargo-culted capabilities. How: - puppetboard cert-generator init: root+APE:true -> uid 1000, drop:[all], APE:false; pod fsGroup 1000; removed trailing `chown -R 1000:1000` (PVC now group-owned). - puppetdb create-log-dir init: root -> uid 999, drop:[all], APE:false; pod fsGroup 999; removed `chown 999:999`. - All OpenVox capability add-lists: removed the duplicate CAP_-prefixed spellings (k8s normalises both to the same kernel cap) and dropped the unused AUDIT_WRITE. - Added allowPrivilegeEscalation:false and seccompProfile RuntimeDefault across the workloads. Stays root (evidence-backed, class-B fallback): the puppetserver master/compiler and puppetdb main containers, plus the perms-and-dirs and generate-types root containers. The OpenVox image entrypoint runs `chown -R puppet:puppet` over root-owned baked-in dirs and drops the JVM to the puppet user via `runuser` (needs CHOWN/SETUID/SETGID); a non-root start crashloops. Their cap sets are reduced to the minimum justified (CHOWN/DAC_OVERRIDE/FOWNER[/SETUID/SETGID]). Validation: `kustomize build --enable-helm` clean; kubeconform 0 invalid / 0 errors; pre-commit (yamllint etc.) green. Confirmed against live pods: puppetserver/puppetdb JVMs already run as puppet/puppetdb via `runuser`; `pam_loginuid` is absent from the su/runuser PAM stacks and loginuid is unset, so dropping AUDIT_WRITE is safe. Post-merge smoke test (puppet had an outage this session — watch closely): after argocd sync, confirm puppetserver master + a compiler reach `running` at /status/v1/simple, puppetdb reaches `running`, puppetboard serves 200, and the generate-types + g10k CronJobs complete — i.e. catalogs still compile and reports still ingest. Closes #307 https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv
unkinben added 1 commit 2026-08-08 22:19:43 +10:00
puppet: reduce privilege in namespace workloads (#307)
ci/woodpecker/pr/vector-test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/kubeconform Pipeline was successful
381734a9c7
Why: shrink the blast radius of the Puppet control-plane pods (CA keys,
eyaml keys, compiled catalogs) per the security sweep in #307 — remove
root where it is not required and strip cargo-culted capabilities.

Changes:
- puppetboard: run the cert-generator init as uid 1000 (was root +
  allowPrivilegeEscalation:true); add pod fsGroup 1000 and drop the
  trailing `chown -R 1000:1000` — the PVC is now group-owned.
- puppetdb: run the create-log-dir init as uid 999 (was root); add pod
  fsGroup 999 and drop its `chown 999:999`.
- All OpenVox capability add-lists: remove the duplicate CAP_-prefixed
  spellings (Kubernetes normalises both to the same kernel cap) and drop
  the unused AUDIT_WRITE.
- Set allowPrivilegeEscalation:false and seccompProfile RuntimeDefault
  across the workloads.

The main puppetserver/puppetdb containers and the perms-and-dirs /
generate-types root containers stay root: the OpenVox entrypoint chowns
root-owned baked-in dirs and drops the JVM to the puppet user via
`runuser` (needs CHOWN/SETUID/SETGID), so a non-root start crashloops.
Their cap sets are reduced to the minimum justified.

Claude-Session: https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv
unkinben force-pushed benvin/puppet-rootless from cd6a596c92 to 381734a9c7 2026-08-08 22:19:43 +10:00 Compare
benvin merged commit 4c2f275f04 into main 2026-08-08 22:36:44 +10:00
benvin deleted branch benvin/puppet-rootless 2026-08-08 22:36:45 +10:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unkin/argocd-apps#319