🧹 k8s: use typed kubelet fields instead of raw configuration dict#2931
🧹 k8s: use typed kubelet fields instead of raw configuration dict#2931tas50 wants to merge 1 commit into
Conversation
6e2770f to
8cd8d85
Compare
|
/review |
8cd8d85 to
478f009
Compare
The os provider (os-13.30.0, mql #8612) exposes typed kubelet accessors that coerce both the config-file and CLI-flag forms and apply kubelet defaults. Migrate the kubelet checks off raw `kubelet.configuration[...]` dict walking: anonymousAuthEnabled, eventRecordQPS, makeIPTablesUtilChains, protectKernelDefaults, readOnlyPort, authorizationMode, tlsCipherSuites, tlsCertFile, tlsPrivateKeyFile, rotateCertificates, clientCAFile Two are behavioral, not cosmetic: - protectKernelDefaults: the old `== "true"` string compare only matched the CLI-flag form; a node setting it via the config file (bool `true`) failed. The typed bool fixes that false negative. - rotateCertificates: the old `!= "false"` passed when the field was absent. The typed bool resolves the effective default (false), so a node that is not actually rotating certificates now correctly fails. readOnlyPort drops its `|| == null` guard — the typed getter always returns a normalized int (0 when unset/disabled). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
478f009 to
9b46e57
Compare
| compliance/vda-isa-5: vda-isa-5-5-2-1 | ||
| mql: | | ||
| kubelet.configuration["protectKernelDefaults"] == "true" | ||
| kubelet.protectKernelDefaults == true |
There was a problem hiding this comment.
🟡 warning — The old check compared protectKernelDefaults against the string "true", but the new check compares against the boolean true. This is a semantic fix (the old check was likely a bug comparing a boolean field to a string), but verify that kubelet.protectKernelDefaults returns a boolean and not a string, otherwise this changes behavior.
| compliance/vda-isa-5: vda-isa-5-5-2-6 | ||
| mql: | | ||
| kubelet.configuration['readOnlyPort'] == 0 || kubelet.configuration['readOnlyPort'] == null | ||
| kubelet.readOnlyPort == 0 |
There was a problem hiding this comment.
🟡 warning — The old check allowed both == 0 and == null (i.e., field not set). The new check only allows == 0. If kubelet.readOnlyPort returns null/nil when the field is unset, this will cause previously-passing checks to fail. Confirm that the typed field defaults to 0 when unset, or re-add the null check: kubelet.readOnlyPort == 0 || kubelet.readOnlyPort == null.
| compliance/vda-isa-5: vda-isa-5-5-1-2 | ||
| mql: | | ||
| kubelet.configuration["rotateCertificates"] != "false" | ||
| kubelet.rotateCertificates == true |
There was a problem hiding this comment.
🟡 warning — The old check was != "false" (pass if not explicitly disabled), but the new check is == true (pass only if explicitly enabled). This is stricter: if the field is unset/null, the old check would pass but the new one would fail. Verify this is the intended behavior, since the default for rotateCertificates in kubelet is true as of K8s 1.19+, so the typed field should reflect that default.
What
Migrates the kubelet checks in
mondoo-kubernetes-securityoff rawkubelet.configuration[...]dict walking to the typed kubelet accessors shipped in os-13.30.0 (mql #8612). The typed getters coerce both the config-file (native bool/int) and CLI-flag (string) forms and apply kubelet defaults, so the queries are shorter and more robust.configuration['authentication']['anonymous']['enabled'] == falsekubelet.anonymousAuthEnabled == falseconfiguration['eventRecordQPS'] == 0kubelet.eventRecordQPS == 0configuration['makeIPTablesUtilChains'] == truekubelet.makeIPTablesUtilChains == trueconfiguration["protectKernelDefaults"] == "true"kubelet.protectKernelDefaults == trueconfiguration['readOnlyPort'] == 0 || ... == nullkubelet.readOnlyPort == 0configuration['authorization']['mode'] != "AlwaysAllow"kubelet.authorizationMode != "AlwaysAllow"configuration['tlsCipherSuites']kubelet.tlsCipherSuitesconfiguration["tlsCertFile"]/["tlsPrivateKeyFile"]kubelet.tlsCertFile/kubelet.tlsPrivateKeyFileconfiguration["rotateCertificates"] != "false"kubelet.rotateCertificates == trueconfiguration['authentication']['x509']['clientCAFile']kubelet.clientCAFileprotectKernelDefaults— the old== "true"string compare only matched the CLI-flag form; a node setting this via the config file (booltrue) silently failed the check. The typed bool coerces both, fixing that false negative.rotateCertificates— the old!= "false"passed when the field was absent. The typed bool resolves the effective default (false), so a node that is not actually rotating certificates now correctly fails. This is more security-correct but will newly flag nodes that previously relied on the lenient check. If we'd rather preserve the CIS-literal "not explicitly false" semantics, shout and I'll adjust.readOnlyPortalso drops its|| == nullguard — the typed getter always returns a normalized int (0when unset/disabled).Dependency
Requires the os-13.30.0 provider (mql #8612 / release #8644). Validated locally against that installed provider.
Testing
cnspec policy lint ./content/mondoo-kubernetes-security.mql.yaml→ valid policy bundle.🤖 Generated with Claude Code