You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
security(umami): the provisioning CronJob runs as uid/gid 1001, below KSV-0020/0021's 10000 floorΒ #3221
All 16 KSV-0020/0021 findings are first-party. 14 of them belong to #3202 β the three OpenBao
writers that share one RWO PVC and must be raised together. The remaining 2 are here:
file
findings
k8s/bases/apps/umami/cron-job.yaml
KSV-0020 Γ1, KSV-0021 Γ1
The pod already sets runAsUser: 1001, runAsGroup: 1001, fsGroup: 1001. KSV-0020/0021 are "runs with UID/GID <= 10000", so the finding is that 1001 is low β not that it is unset. Raising it
is the whole change.
An earlier revision of this issue stated the cause as a missing runAsUser/runAsGroup across four
files. That was wrong on all four; the correction and the per-file measurement are in this comment.
Why this is not a one-line edit
The umami provisioning CronJob runs ghcr.io/umami-software/umami, whose image bakes uid 1001. Raising
the pod to an arbitrary high UID only works if nothing in the image's filesystem is owned by 1001 in a
way the process needs to write, and if fsGroup covers whatever it does write. A wrong value fails the
provisioning run rather than erroring at apply time β the manifest validates either way.
Unlike the vault trio, umami shares no volume with another workload, so it can move on its own.
Acceptance criteria
Determine the UID/GID the umami image actually runs as, and what it writes, from the image
config rather than assumption.
Raise runAsUser/runAsGroup above 10000, with fsGroup matching whatever it writes.
Demonstrate the provisioning CronJob still completes successfully after the change β a green
apply is not evidence. This is the work; the diff is trivial.
trivy KSV-0020/0021 drop by exactly 2, measured with scripts/megalinter-scan-counts.sh --trivy-only.
Size
Small diff, medium verification cost. The verification needs the job actually run, and the agent has
read-only cluster access β which is why this stayed split out of #2787 rather than being folded into a
disposition PR.
Independently re-measured on main @2199c715 with scripts/megalinter-scan-counts.sh --trivy-only. I reached this issue's exact per-file breakdown from a separate starting point, so the 16 stand confirmed:
file
findings
KSV-0020
KSV-0021
vault-config/job.yaml
6
2
4
vault-backup/cron-job.yaml
4
2
2
vault-backup/job.yaml
4
2
2
umami/cron-job.yaml
2
1
1
Tree total has moved: 45 β 36, and β 32 once #3231 lands (it dispositions the 4 vendored-bundle findings this issue correctly excludes). 0 CRITICAL, 0 HIGH. The 16 here are now half of everything trivy still reports on k8s/, so this issue is the critical path to removing REPOSITORY_TRIVY from DISABLE_ERRORS_LINTERS.
One premise needs correcting
they fire because the container sets runAsNonRoot: true but no explicit runAsUser/runAsGroup
That is true for the three vault jobs, but not for umami. k8s/bases/apps/umami/cron-job.yaml pins a UID explicitly:
So umami is a deliberately low UID, not an absent one β a different problem needing a different fix. The vault jobs need a value chosen; umami needs an existing value changed, which is the riskier of the two because fsGroup: 1001 already governs volume ownership.
Two additions worth folding into the acceptance criteria
vault-config/job.yaml is already known to be image-baked. It carries a scoped checkov.io/skip2 recording exactly that, and sets runAsUser per container instead. That is strong prior evidence for how at least those 6 resolve β worth confirming rather than re-deriving.
Correction: the stated cause does not hold β every file named here already sets an explicit UID and GID
Measured on main @4d2a3dc4 with this repository's own scripts/megalinter-scan-counts.sh --trivy-only
(trivy 0.74.0, scan rooted at the repository root), plus a per-target JSON breakdown of the same scan.
This issue says the findings fire because a container "sets runAsNonRoot: true but no explicit runAsUser/runAsGroup". That is not what the tree contains. All four files set both fields:
KSV-0020/0021 are "runs with UID/GID <= 10000", not "UID/GID unset". The findings fire because the
values are low, not because they are missing. So acceptance criterion 2 as written ("Set explicit runAsUser/runAsGroup") is already satisfied everywhere, and criterion 1 ("determine the UID
each image actually runs as") is already answered in-tree: vault-config's own checkov.io/skip2 records that UID 100 is the openbao image's baked openbao:x:100:1000 user.
In vault-config/job.yaml the findings are per-container overrides, not the pod default β the pod
runs 65532, and four containers (fetch-snapshot, store-keys, vault-init, vault-config) restate
the lower openbao identity. An implementer reading the current text would go looking for an absent
field and find it present in all four files.
Current counts, and why the vendored remainder is gone
All 16 KSV-0020/0021 are now first-party and land in exactly the four files above (9 + 7 = 16,
verified per target). The "remaining 4 in the vendored CDI/KubeVirt bundles" this issue mentions were
dispositioned by #3220, so the split it describes no longer exists.
Overlap with #3202 β 14 of the 16 are already owned
#3202 (filed earlier, 01:12Z the same day) covers making the snapshot group-readable and then
raising the writers' UIDs, and it correctly captures the constraint this issue does not: the three
writers share one RWO PVC and must move together, because the snapshot lands -rw------- owned by 100:1000 and minio/mc can only read it as its owner. That is vault-config/job.yaml, vault-backup/job.yaml and vault-backup/cron-job.yaml β 14 of the 16 findings.
k8s/bases/apps/umami/cron-job.yaml (2 findings) is the only part not covered there. It shares no
volume with the vault writers, so it can move independently.
What this issue is being rescoped to
Retitled and rewritten to cover umami only, with the vault trio left to #3202. The original
premise is preserved here rather than silently overwritten.
The verification bar is unchanged and is still the hard part: raising umami's UID has to be shown not
to break the provisioning run, and this agent has read-only cluster access.
changed the title [-]vault-backup, vault-config and umami jobs run without an explicit UID/GID[/-][+]security(umami): the provisioning CronJob runs as uid/gid 1001, below KSV-0020/0021's 10000 floor[/+]on Aug 19, 2026
Criterion 3 is met in production β observed, not inferred
#3249 merged at 19:05:43Z. The acceptance criterion this issue called "the work" β demonstrate the
provisioning CronJob still completes, explicitly noting a green apply is not evidence β is now
satisfied by the real workload, read from the live cluster:
job
securityContext
result
ran
umami-provision-tenants-29786100 (scheduled)
uid/gid/fsGroup 1001
succeeded=1
19:00:00 β 19:00:12Z
umami-provision-tenants-bootstrap (post-deploy)
uid/gid/fsGroup 65534
succeeded=1
19:02:31 β 19:02:38Z
That is a natural before/after pair two minutes apart on the same cluster against the same Umami API:
the last run under the old ids succeeded, and the first run under the new ids succeeded too. The live
CronJob spec now reads runAsUser/runAsGroup/fsGroup: 65534, so the change reconciled rather than
merely merging.
The container evidence in #3249 predicted this; it did not establish it. This does.
One correction to the record
A comment on #3249 said the merge_group deploy's inline tenant provisioning exercises this workload,
citing the repository's own AGENTS.md. The π Deploy to Prod job did run and succeed for pr-3249 β that part is confirmed from the jobs API β but I could not read its log (the log endpoint
returned zero lines), so I never verified that it specifically provisioned umami. The claim was a
reasonable inference from documentation, not a measurement, and it should not be read as one. The
cluster evidence above stands on its own and does not depend on it.
Closing the loop: this can move straight to Done rather than sitting in Verifying.
Activity
devantler commentedon Aug 19, 2026
Currency + one premise correction
Independently re-measured on
main@2199c715withscripts/megalinter-scan-counts.sh --trivy-only. I reached this issue's exact per-file breakdown from a separate starting point, so the 16 stand confirmed:vault-config/job.yamlvault-backup/cron-job.yamlvault-backup/job.yamlumami/cron-job.yamlTree total has moved: 45 β 36, and β 32 once #3231 lands (it dispositions the 4 vendored-bundle findings this issue correctly excludes). 0 CRITICAL, 0 HIGH. The 16 here are now half of everything trivy still reports on
k8s/, so this issue is the critical path to removingREPOSITORY_TRIVYfromDISABLE_ERRORS_LINTERS.One premise needs correcting
That is true for the three vault jobs, but not for umami.
k8s/bases/apps/umami/cron-job.yamlpins a UID explicitly:So umami is a deliberately low UID, not an absent one β a different problem needing a different fix. The vault jobs need a value chosen; umami needs an existing value changed, which is the riskier of the two because
fsGroup: 1001already governs volume ownership.Two additions worth folding into the acceptance criteria
vault-config/job.yamlis already known to be image-baked. It carries a scopedcheckov.io/skip2recording exactly that, and setsrunAsUserper container instead. That is strong prior evidence for how at least those 6 resolve β worth confirming rather than re-deriving.scripts/tests/test-trivyignore-vendored-operator-boundary.shasserts the vendored ones β otherwise it silently stops being path-scoped. That is the defect Three vendored-bundle trivy dispositions are outside the boundary test that is meant to keep them scopedΒ #3230 is about, and this issue would otherwise reintroduce it.chore: agent-claim #3221 nonce=8a1106022f6c6f8988655754ce4a3696
devantler commentedon Aug 19, 2026
Correction: the stated cause does not hold β every file named here already sets an explicit UID and GID
Measured on
main@4d2a3dc4with this repository's ownscripts/megalinter-scan-counts.sh --trivy-only(trivy 0.74.0, scan rooted at the repository root), plus a per-target JSON breakdown of the same scan.
This issue says the findings fire because a container "sets
runAsNonRoot: truebut no explicitrunAsUser/runAsGroup". That is not what the tree contains. All four files set both fields:k8s/bases/infrastructure/vault-config/job.yamlrunAsUser: 65532,runAsGroup: 1000,fsGroup: 1000k8s/bases/infrastructure/vault-backup/job.yamlrunAsUser: 100,runAsGroup: 1000,fsGroup: 1000k8s/bases/infrastructure/vault-backup/cron-job.yamlrunAsUser: 100,runAsGroup: 1000,fsGroup: 1000k8s/bases/apps/umami/cron-job.yamlrunAsUser: 1001,runAsGroup: 1001,fsGroup: 1001KSV-0020/0021 are "runs with UID/GID <= 10000", not "UID/GID unset". The findings fire because the
values are low, not because they are missing. So acceptance criterion 2 as written ("Set explicit
runAsUser/runAsGroup") is already satisfied everywhere, and criterion 1 ("determine the UIDeach image actually runs as") is already answered in-tree:
vault-config's owncheckov.io/skip2records that UID 100 is the openbao image's bakedopenbao:x:100:1000user.In
vault-config/job.yamlthe findings are per-container overrides, not the pod default β the podruns 65532, and four containers (
fetch-snapshot,store-keys,vault-init,vault-config) restatethe lower openbao identity. An implementer reading the current text would go looking for an absent
field and find it present in all four files.
Current counts, and why the vendored remainder is gone
All 16 KSV-0020/0021 are now first-party and land in exactly the four files above (9 + 7 = 16,
verified per target). The "remaining 4 in the vendored CDI/KubeVirt bundles" this issue mentions were
dispositioned by #3220, so the split it describes no longer exists.
Overlap with #3202 β 14 of the 16 are already owned
#3202 (filed earlier, 01:12Z the same day) covers making the snapshot group-readable and then
raising the writers' UIDs, and it correctly captures the constraint this issue does not: the three
writers share one RWO PVC and must move together, because the snapshot lands
-rw-------owned by100:1000andminio/mccan only read it as its owner. That isvault-config/job.yaml,vault-backup/job.yamlandvault-backup/cron-job.yamlβ 14 of the 16 findings.k8s/bases/apps/umami/cron-job.yaml(2 findings) is the only part not covered there. It shares novolume with the vault writers, so it can move independently.
What this issue is being rescoped to
Retitled and rewritten to cover umami only, with the vault trio left to #3202. The original
premise is preserved here rather than silently overwritten.
The verification bar is unchanged and is still the hard part: raising umami's UID has to be shown not
to break the provisioning run, and this agent has read-only cluster access.
[-]vault-backup, vault-config and umami jobs run without an explicit UID/GID[/-][+]security(umami): the provisioning CronJob runs as uid/gid 1001, below KSV-0020/0021's 10000 floor[/+]chore: agent-claim #3221 nonce=40b0f21075f4984dd591076f404e3387
devantler commentedon Aug 19, 2026
Criterion 3 is met in production β observed, not inferred
#3249 merged at 19:05:43Z. The acceptance criterion this issue called "the work" β demonstrate the
provisioning CronJob still completes, explicitly noting a green apply is not evidence β is now
satisfied by the real workload, read from the live cluster:
umami-provision-tenants-29786100(scheduled)succeeded=1umami-provision-tenants-bootstrap(post-deploy)succeeded=1That is a natural before/after pair two minutes apart on the same cluster against the same Umami API:
the last run under the old ids succeeded, and the first run under the new ids succeeded too. The live
CronJob spec now reads
runAsUser/runAsGroup/fsGroup: 65534, so the change reconciled rather thanmerely merging.
The container evidence in #3249 predicted this; it did not establish it. This does.
One correction to the record
A comment on #3249 said the
merge_groupdeploy's inline tenant provisioning exercises this workload,citing the repository's own
AGENTS.md. Theπ Deploy to Prodjob did run and succeed forpr-3249β that part is confirmed from the jobs API β but I could not read its log (the log endpointreturned zero lines), so I never verified that it specifically provisioned umami. The claim was a
reasonable inference from documentation, not a measurement, and it should not be read as one. The
cluster evidence above stands on its own and does not depend on it.
Closing the loop: this can move straight to Done rather than sitting in Verifying.