RavenDB-27110: harden RavenDB pod security context, fix PVC permissions#40
Open
poissoncorp wants to merge 1 commit into
Open
RavenDB-27110: harden RavenDB pod security context, fix PVC permissions#40poissoncorp wants to merge 1 commit into
poissoncorp wants to merge 1 commit into
Conversation
The operator ran containers as uid/gid 999 (the RavenDB image's USER) but never told Kubernetes to prepare mounted volumes for that identity. On storage providers that mount freshly provisioned PVCs root-owned (e.g. Longhorn), RavenDB failed at startup with a DataDir permission error. Reported twice independently: issue #37 (Kyverno workaround) and PR #39 (fsGroup patch). Address the root instead of the symptom: - pkg/common: single source of truth for the runtime identity (RavenDBUID/RavenDBGID = 999), mirroring the image USER. No more bare 999. - pkg/resource/security.go: shared container and pod security-context builders, compatible with the PodSecurity "restricted" profile (runAsNonRoot, fsGroup with OnRootMismatch, allowPrivilegeEscalation false, drop ALL capabilities, seccompProfile RuntimeDefault). Dropping ALL is safe because the low-port sysctl makes 443 unprivileged. - Apply to both the StatefulSet pod/container and the bootstrapper Job pod/container. The Job container previously had no security context at all. - Rendered-spec unit tests assert the context is wired through BuildStatefulSet and BuildJob, not just the helpers in isolation. CI now runs ./pkg/... too. - hack/verify-image-uid.sh + image-uid-guard.yml: CI guard asserting the upstream image still uses uid/gid 999, so drift fails in CI, not on a cluster. - Docs: SECURITY.md posture + supported version bump, operator chart README "Pod security" section, CLAUDE.md convention note. Closes #37. Supersedes #39. Co-authored-by: Jason Kossis <jkossis@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The operator ran RavenDB containers as uid/gid 999 (the image's
USER ravendb) but never told Kubernetes to prepare mounted volumes for that identity. On storage providers that mount freshly provisioned PVCs root-owned (e.g. Longhorn), RavenDB fails at startup with:Reported twice, independently: #37 (Kyverno
fsGroupworkaround) and #39 (fsGroup patch). This addresses the root instead of the symptom, and hardens the pods while we are in there.What changed
pkg/common.RavenDBUID/RavenDBGID = 999, mirroring the imageUSER. No more bare999copied across files.pkg/resource/security.go), compatible with the PodSecurityrestrictedprofile:fsGroup: 999(+fsGroupChangePolicy: OnRootMismatch),runAsNonRoot,seccompProfile: RuntimeDefaultrunAsUser/runAsGroup 999,runAsNonRoot,allowPrivilegeEscalation: false, dropALLcapabilities,seccompProfile: RuntimeDefaultnet.ipv4.ip_unprivileged_port_start=0, soNET_BIND_SERVICEis not needed. The StatefulSet keeps the sysctl; the Job does not (it binds no low ports).Why fsGroup (root cause)
The image ships
/var/lib/ravendb/dataasroot:ravendb 0770, so gid 999 can write. A PVC mount masks that with the volume root (oftenroot:root), destroying the group-writable property.fsGroup: 999restores it. It cannot be inferred from the image, so the value is restated in code (see the CI guard below).Tests & guards
BuildStatefulSetandBuildJob(not the helpers in isolation), including that pod fsGroup matches the container identity. CI now runs./pkg/...too.hack/verify-image-uid.sh+.github/workflows/image-uid-guard.ymlassert the upstream image still uses uid/gid 999, so a UID change fails in CI, not on a user's cluster.Not verified in CI here
Live PodSecurity
restrictedadmission and the original root-owned-PVC failure need a specific storage backend; the original bug was validated on Longhorn (#39). The e2e suite still exercises that pods start.Docs
SECURITY.md(posture + supported-version bump), operator chart README "Pod security" section, CLAUDE.md convention note.Closes #37.
Supersedes #39. Credit to @jkossis, whose #39 seeded the fsGroup fix (co-authored on the commit).