Skip to content

🧹 k8s: use typed kubelet fields instead of raw configuration dict#2931

Open
tas50 wants to merge 1 commit into
mainfrom
simplify/k8s-typed-kubelet
Open

🧹 k8s: use typed kubelet fields instead of raw configuration dict#2931
tas50 wants to merge 1 commit into
mainfrom
simplify/k8s-typed-kubelet

Conversation

@tas50

@tas50 tas50 commented Jun 23, 2026

Copy link
Copy Markdown
Member

What

Migrates the kubelet checks in mondoo-kubernetes-security off raw kubelet.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.

Field Before After
anonymous auth configuration['authentication']['anonymous']['enabled'] == false kubelet.anonymousAuthEnabled == false
event QPS configuration['eventRecordQPS'] == 0 kubelet.eventRecordQPS == 0
iptables chains configuration['makeIPTablesUtilChains'] == true kubelet.makeIPTablesUtilChains == true
protect kernel configuration["protectKernelDefaults"] == "true" kubelet.protectKernelDefaults == true
read-only port configuration['readOnlyPort'] == 0 || ... == null kubelet.readOnlyPort == 0
authz mode configuration['authorization']['mode'] != "AlwaysAllow" kubelet.authorizationMode != "AlwaysAllow"
cipher suites configuration['tlsCipherSuites'] kubelet.tlsCipherSuites
serving cert/key configuration["tlsCertFile"] / ["tlsPrivateKeyFile"] kubelet.tlsCertFile / kubelet.tlsPrivateKeyFile
rotate certs configuration["rotateCertificates"] != "false" kubelet.rotateCertificates == true
client CA configuration['authentication']['x509']['clientCAFile'] kubelet.clientCAFile

⚠️ Two behavioral changes (not just cosmetic)

  • protectKernelDefaults — the old == "true" string compare only matched the CLI-flag form; a node setting this via the config file (bool true) 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.

readOnlyPort also drops its || == null guard — the typed getter always returns a normalized int (0 when 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

@mondoo-code-review mondoo-code-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean migration from raw dict access to typed kubelet fields, with two semantic changes worth verifying.

Comment thread content/mondoo-kubernetes-security.mql.yaml
Comment thread content/mondoo-kubernetes-security.mql.yaml
Comment thread content/mondoo-kubernetes-security.mql.yaml
@github-actions

github-actions Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Test Results

  1 files  ±0   44 suites  ±0   1m 44s ⏱️ +5s
854 tests ±0  853 ✅ ±0  1 💤 ±0  0 ❌ ±0 
855 runs  ±0  854 ✅ ±0  1 💤 ±0  0 ❌ ±0 

Results for commit 9b46e57. ± Comparison against base commit 5c0d2f3.

♻️ This comment has been updated with latest results.

@tas50 tas50 force-pushed the simplify/k8s-typed-kubelet branch from 6e2770f to 8cd8d85 Compare June 26, 2026 20:45

@mondoo-code-review mondoo-code-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean migration from raw dict access to typed fields with minor semantic changes worth verifying.

Comment thread content/mondoo-kubernetes-security.mql.yaml
Comment thread content/mondoo-kubernetes-security.mql.yaml
Comment thread content/mondoo-kubernetes-security.mql.yaml
@tas50

tas50 commented Jun 26, 2026

Copy link
Copy Markdown
Member Author

/review

@mondoo-code-review mondoo-code-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean migration from raw dict access to typed fields, with two semantic changes worth verifying.

Comment thread content/mondoo-kubernetes-security.mql.yaml
Comment thread content/mondoo-kubernetes-security.mql.yaml
Comment thread content/mondoo-kubernetes-security.mql.yaml
@tas50 tas50 force-pushed the simplify/k8s-typed-kubelet branch from 8cd8d85 to 478f009 Compare June 26, 2026 21:17

@mondoo-code-review mondoo-code-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean migration from raw dict access to typed fields, with two behavioral changes worth verifying.

Comment thread content/mondoo-kubernetes-security.mql.yaml
Comment thread content/mondoo-kubernetes-security.mql.yaml
Comment thread content/mondoo-kubernetes-security.mql.yaml
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>
@tas50 tas50 force-pushed the simplify/k8s-typed-kubelet branch from 478f009 to 9b46e57 Compare June 29, 2026 17:22

@mondoo-code-review mondoo-code-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean migration from raw config dict to typed fields with minor behavioral changes worth noting

compliance/vda-isa-5: vda-isa-5-5-2-1
mql: |
kubelet.configuration["protectKernelDefaults"] == "true"
kubelet.protectKernelDefaults == true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant