Repository navigation
Description
π€ Generated by the Agentic Engineer
Evidence
Re-measured with the repository's own scripts/megalinter-scan-counts.sh (the reproduction of CI's
invocation β a hand-rolled checkov run measures a different thing and produced a wrong plan once
already, see #2787). Current CI-equivalent posture is 12 failing checks, all kubernetes
framework, after #3017 cleared the six probe findings.
CKV_K8S_35 β "prefer using secrets as files over secrets as environment variables" β is 4 of those
12, and it is the largest group with no disposition and no child issue. Every other remaining group
is already owned: CKV_K8S_40 by #2898 and #2904, CKV_K8S_38 by #2845, and the three singletons are
individually dispositionable.
The four sites span an application CronJob, an observability CronJob, and two controller workloads in
the docker provider overlay; all are derivable from the scan output rather than listed here.
Why this one is different from its siblings
The dispositions that came before it were verdicts β is this UID load-bearing, is this token
needed, is this pod real. This group is not: mounting a secret as a file instead of an environment
variable is a behavioural change to each workload, because the process has to read a path rather
than an env var, and for a third-party image that depends on whether the image supports a
*_FILE-style convention at all. So it cannot be settled by one risk acceptance the way #2904 settles
CKV_K8S_40.
Why it is worth doing rather than excepting
An environment variable is readable by anything that can inspect the process β including /proc,
crash dumps, and most logging middleware that dumps the environment β whereas a mounted file is
scoped by filesystem permissions and can be rotated in place without a restart. That is a real
reduction in exposure, not a scanner formality.
Expected behaviour
Each of the four either mounts its secret as a file, or carries a scoped checkov.io/skip naming the
concrete image constraint that prevents it β the same fix-vs-except ladder the sibling issues use, and
never a disabled check.
Acceptance criteria
- Each of the four sites is either converted to a file mount or carries a scoped skip naming the
image constraint, verified per-image rather than assumed. -
scripts/megalinter-scan-counts.shreports 0 CKV_K8S_35 and a total of 8. - A newly added workload passing a secret via
envis still flagged (ablation, as in fix(security): disposition the six unreachable-probe checkov findingsΒ #3017). - The counts recorded in
.mega-linter.ymlare corrected in the same PR.
Rough size: medium β four sites, each needing its image checked before choosing fix or skip.
Part of #2787
Metadata
Metadata
Assignees
Labels
Type
Fields
Projects
- StatusShow more project fieldsβ Done
Activity
coderabbitai commentedon Aug 8, 2026
π Related PRs
#2860 - security(k8s): record an explicit service-account-token verdict per workload [merged]
#2893 - security(k8s): disposition CKV_SECRET_6 as key references, not secret material [merged]
#2900 - security(k8s): withdraw the CKV_K8S_40 suppressions whose reasons do not hold [merged]
#2911 - fix(security): disposition the three unconstrained CKV_K8S_40 sites [merged]
#2929 - fix(security): preserve vendored Checkov dispositions [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!
devantler commentedon Aug 11, 2026
The group is down to 1 of 4, and two of them were not fixable
Measured on
fc812a37withscripts/megalinter-scan-counts.sh --checkov-only(checkov 3.3.0 local;CI runs 3.3.2): the whole checkov backlog is 7, of which CKV_K8S_35 Γ3 β and 5 / Γ1 with
#3086 applied.
mcbucket Job (docker provider)Correcting this issue's premise
This issue says the group is "worth doing rather than excepting", on the reasoning that mounting a
file instead of an env var is a behavioural change we can make, gated on "whether the image
supports a
*_FILE-style convention at all". For the MinIO pair the answer to that gate is no,and it is worth recording so it is not re-litigated:
MINIO_ROOT_USER/MINIO_ROOT_PASSWORDand it exposes no file-based equivalent. The*_FILEspelling thatcirculates for other images is undocumented for the MinIO server and reported not to initialise it,
so adopting it would trade a scanner finding for a test-bed that silently fails to start.
mcclient β no documented file-based credential input. Reading a mounted file in the shellwould move the value into the process argv, which is not an improvement over the environment.
Hand-writing
mc's ownconfig.jsonis the only genuinely file-based route and depends on aninternal format platform CI cannot verify: static validation only, no full-cluster system test.
An unverifiable change to the local backup test-bed would surface as a silent breakage the next
time someone ran it.
Both are the local Docker test-bed rather than a production credential, which is why an exception is
proportionate here and would not be for umami. Both carry a resource-scoped
checkov.io/skip, nevera disabled check β verified by ablation in both directions: removing an annotation brings its finding
back, and a newly added workload reading a Secret from the environment in the same namespace is
still flagged.
What remains
Only the umami provisioning CronJob, and it is the one site where the fix is available: its
consumer is a Node script defined inline in the same manifest, so it can read a mounted path
directly. The non-obvious part is the
TENANTScontract, which wires members by environmentvariable name (
"passwordEnv": "ASCOACHINGOGVANER_PASSWORD"), so that indirection and itsonboarding comment change with it. It is also a production workload holding an admin credential, and
deployed only to the Hetzner provider β so behavioural proof is post-merge, on the next 15-minute
tick.
Acceptance for closing this issue is therefore just that one site:
checkovreports 0CKV_K8S_35, with the ablation control still flagging a new env-var secret.(I briefly filed #3087 for that last site before spotting this issue already owned the group; #3087
is closed as superseded and its detail is folded in above.)
security(checkov): read MinIO's root credential from a file instead oβ¦
devantler commentedon Aug 19, 2026
Measurement update β the counts in the body are stale, the issue is not
Re-measured on
main@4d2a3dc4withscripts/megalinter-scan-counts.sh --checkov-only:The body's "12 failing checks, of which CKV_K8S_35 is 4" no longer describes the tree β checkov is at
zero and is a blocking gate again (#3205).
That is not because this issue was resolved. Exactly one CKV_K8S_35 site remains, and it is
suppressed by an annotation that defers to this issue:
So the zero is partly held up by this deferral. The other three sites were addressed on their own
merits (#3117 moved the umami provisioning secrets to files; the coroot cron-jobs carry reasoned
in-line explanations rather than skips).
Scope now: 1 site, not 4 β the minio bootstrap Job in the docker provider, whose blocker is
stated in the annotation itself:
mc alias importis the file-based route, but adopting itrestructures the Job's wait loop, and no local environment exercises the result.
Leaving this open deliberately: closing it would orphan an annotation that points here, and the
suppression would then have no tracking issue behind it.
chore: agent-claim #3018 nonce=c49e2a2f414b445d92c8d16b6f543bb7
chore: agent-claim #3018 nonce=735b804a7d6e94d5c19d3568c7e95650
devantler commentedon Aug 22, 2026
Completion verification β 2026-08-22
Verified against current
main@64c4ba23027b057f7bd89961cd426610f89186e9:scripts/megalinter-scan-counts.sh --checkov-onlyreports 0 failing checks across thecloudformation,kubernetes, andgithub_actionsframeworks, with the expected single parsing error. The local Checkov is 3.3.10 while CI pins 3.3.9; the current default head is also green, so the repository-owned exact-version gate agrees with the local zero.secretKeyRef/secretReforMC_HOST_*credential reaches the environment, no credential enters argv, the mounted file is imported directly, and noCKV_K8S_35skip remains.secretKeyRefenvironment variable is still rejected byCKV_K8S_35, proving the zero is not caused by disabling the check.The last tracked deferral was removed by #3245 through completed child #3247. The historical acceptance target of 8 total findings has been surpassed by later security slices: the current comparable total is 0, and
.mega-linter.ymlalready records that current baseline.All remaining acceptance criteria are satisfied, so this parent is complete.