Repository navigation
Description
🤖 Generated by the Agentic Engineer
Evidence
k8s/bases/infrastructure/vault-config/job.yaml sets pod-level runAsUser: 65532,
runAsGroup: 1000, fsGroup: 1000, and then overrides runAsUser: 100 on only the two openbao
containers (vault-init, vault-config).
That per-container split is deliberate and well-reasoned. The manifest's own comment explains it:
a checkov.io/skipN directive is resource-scoped, so setting UID 100 at pod level would have
silenced CKV_K8S_40 for every container while minio/mc and alpine/k8s bake no uid-100
entry of their own — "an unjustified low-UID execution that this annotation then hid".
I verified the premise behind that split against the pinned digest rather than assuming it:
$ docker run --rm --entrypoint sh quay.io/openbao/openbao:2.5.3@sha256:fdc6da21... \
-c "grep -E ^openbao /etc/passwd; grep -E :1000: /etc/group"
openbao:x:100:1000::/home/openbao:/sbin/nologin
openbao:x:1000:openbao
So 100:1000 is genuinely the image's baked identity, and the reasoning holds — for the UID.
It was not carried through to the GID. runAsGroup: 1000 is only ever set at pod level, so
fetch-snapshot (minio/mc) and store-keys (alpine/k8s) run with primary GID 1000 — the
openbao group — which their images no more define than they define uid 100. That is the same
class of unjustified low identity the UID split exists to prevent, one axis over.
trivy reports it as KSV-0021 on all four containers (lines 147, 202, 433, 473). Two of those four
are the image-baked openbao pair and are the accepted class; the other two are this gap.
Who this affects
Low severity and not a live compromise: both containers already run a high, non-root UID, and the
group grants no access beyond the shared emptyDir volumes. What it costs is that the file cannot
reach KSV-0021: 0, so #2787 cannot restore trivy as a hard gate while it stands — and a
path-scoped disposition cannot separate the two real findings from the two accepted ones, because
trivy scopes by file, not by line.
Expected behaviour
fetch-snapshot and store-keys carry an explicit high runAsGroup matching their high
runAsUser, leaving the openbao pair on their image-baked 100:1000.
Why this needs a proving run rather than a direct PR
runAsGroup sets the primary GID only — fsGroup is added to every container as a
supplementary group, so volume access survives the change. (The existing KSV-0021 disposition
in .trivyignore.yaml states this same distinction.)
The risk is file ownership, not access: fetch-snapshot downloads the snapshot that the
openbao vault-init container then reads. Files it creates would become group-owned 65532 instead
of 1000, so any mode without world-read would break vault-init. That is exactly the failure
#3202 found on the neighbouring vault-backup writers, where a 0440 file owned root:65534 read
fine as 65534 but gave EACCES as 1001.
So the change needs the created files' modes checked and a real Job run observed, which is also
why this is filed rather than shipped speculatively.
Acceptance criteria
-
fetch-snapshotandstore-keysset an explicitrunAsGroupabove 10000. - The openbao containers still run
100:1000. - A real
vault-configJob run completes: the snapshotfetch-snapshotwrites is readable by
vault-init, andstore-keysstill writes theopenbao-unsealSecret. - trivy
KSV-0021on this file drops from 4 to 2, and the residual two are the openbao pair.
Rough size: small, gated on one observed Job run.
Part of #2787
Metadata
Metadata
Assignees
Labels
Type
Fields
Projects
- StatusShow more project fields✅ Done
Activity
coderabbitai commentedon Aug 19, 2026
🔗 Related PRs
#3249 - security(umami): raise the provisioning CronJob above the UID/GID floor [merged]
#3203 - security(vault-backup): disposition the last two CKV_K8S_40 findings as one deferred exception [merged]
#3246 - security(vault-backup): make the raft snapshot group-readable [merged]
#3231 - chore(security): disposition KSV-0020/0021 on the vendored VM operators [merged]
#3236 - security(k8s): disposition the 8 RBAC-breadth trivy findings [merged]
📝 Issue Planner
Check the box below or use the
@coderabbitai plancommand to generate an implementation plan and prompts that you can use with your favorite coding assistant.🧪 Issue enrichment is currently in open beta.
You can configure auto-planning by selecting labels in the issue_enrichment configuration.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord!
chore: agent-claim #3255 nonce=e22ee531f70fc014ab3173977e03f0fa
devantler commentedon Sep 1, 2026
Closing as already delivered — every acceptance criterion is met at
mainThis issue duplicates #3258 (CodeRabbit flagged the pair on 2026-08-19), which #3264
"fix(vault-config): scope the low GID to the two openbao containers" closed on 2026-08-20. The
fix landed while this issue stayed open, so I verified all four criteria against live state rather
than inheriting that closure.
AC1 —
fetch-snapshotandstore-keysrun a primary GID above 10000 — met, by a better shapeStated as "set an explicit
runAsGroupabove 10000" per container; delivered as an explicitpod-level
runAsGroup: 65532that those two containers take, with the override moved onto theopenbao pair instead. Same outcome with two fewer per-container blocks, and it makes the high
identity the default rather than something each new container must remember to restate. Recording
the deviation rather than quietly reading it as satisfied.
AC2 — the openbao containers still run
100:1000— metvault-initandvault-configeach carryrunAsUser: 100/runAsGroup: 1000;fetch-snapshotand
store-keyscarry neither and inherit the pod default.AC3 — a real Job run completes — met, observed post-merge on the live cluster
Recorded on #3258: the
merge_groupdeploy for #3264 succeeded,🩹 Heal Prodwas skipped, andJob.openbao.vault-configreportedsucceeded=1(04:05:28Z → 04:06:33Z, 65s) with the containerson differing primary GIDs —
store-keysread/sharedwritten byvault-initat gid 1000, andvault-initread/snapshotswritten byfetch-snapshotat gid 65532. That is the property thisissue's "why this needs a proving run" section identified as the risk, and it held.
Re-confirmed live today: all three
openbao-*pods1/1 Running(readiness requires unsealed), andthe
infrastructureKustomizationREADY=Trueat the current revision. The Job object itself isgone, as
ttlSecondsAfterFinished: 600intends.AC4 — trivy
KSV-0021drops from 4 to 2, residual being the openbao pair — met, measuredScanning the raw manifest (trivy 0.74.0), with a paired negative control against the pre-fix blob
49d88512^:49d88512^)main(731537ec)vault-init, 486vault-config— the openbao pairThe control fires, so the measurement discriminates rather than merely agreeing. The repository then
goes one step further than this criterion asked: #3264 added a path-scoped
KSV-0021disposition on the image-baked-identity premise, asserted by
scripts/tests/test-trivyignore-vault-config-identity-boundary.sh, so the dispositioned count is0 and #2787 is no longer held open by this file.
No code change is needed. Closing as completed by #3264; the durable record lives on #3258.