Skip to content

feat(kube): allow mutating kubectl when write permissions enabled - #475

Merged
mayankpande88 merged 3 commits into
mainfrom
feat/kubectl-write-mode
Jun 12, 2026
Merged

feat(kube): allow mutating kubectl when write permissions enabled#475
mayankpande88 merged 3 commits into
mainfrom
feat/kubectl-write-mode

Conversation

@mayankpande88

Copy link
Copy Markdown
Contributor

Problem

kubectl_command_executor enforced a read-only verb allowlist unconditionally. On installs that grant the runner write RBAC (runner.enableWritePermissions: true), mutating commands were still rejected:

err: kubectl: verb "scale" not in read-only allowlist; mutating actions go through pkg/mutate
err: kubectl: verb "patch" not in read-only allowlist; ...
err: kubectl: verb "set" not in read-only allowlist; ...
err: kubectl: verb "-n" not in read-only allowlist; ...   # ← also a parsing bug

The legacy robusta executor ran these via KUBECTL_ALLOW_CRUD (defaulted on); the Go rewrite made the allowlist a hard gate with no escape hatch.

Changes

  • Write mode gated on runner.enableWritePermissions. New KUBECTL_ALLOW_WRITE env, emitted by the chart from the same flag that grants the write ClusterRole — so the runner allowlist and cluster RBAC move together. Default false keeps kubectl strictly read-only; mutations still route to the signed pkg/mutate actions. When true, mutating verbs run and the API server's RBAC becomes the enforcement boundary.
  • Fixed verb resolution past leading global flags. kubectl -n ns get pods was rejected as verb -n. firstVerb() now skips -n/--namespace/--context/-o/--kubeconfig/etc. before validating. Mutating verbs hidden behind a flag (-n default scale ...) are still caught when write mode is off.

Security posture

When write mode is on, mutating kubectl flows over the unsigned, relay-secret-gated light-action path — the same posture as the existing pod_script_run_enricher. The operator who sets enableWritePermissions: true (granting write RBAC) is explicitly opting into cluster writes. Default-off installs are unchanged and strictly read-only.

Tests

Added coverage for: reads behind global flags, rejection of mutations behind flags (no bypass), AllowWrite permitting mutations, and flags-only input. go test ./pkg/kube/ ./pkg/config/ passes; chart renders KUBECTL_ALLOW_WRITE: "false" by default.

kubectl_command_executor enforced a read-only verb allowlist
unconditionally, so scale/patch/set/delete were rejected even on
installs that grant the runner write RBAC. Gate the allowlist on the
existing runner.enableWritePermissions chart flag (the same switch that
grants the write ClusterRole) via a new KUBECTL_ALLOW_WRITE env. Default
stays read-only; when enabled, mutating verbs run and the API server's
RBAC is the enforcement boundary. Same unsigned, relay-secret-gated
posture as pod_script_run_enricher.

Also fix verb resolution to skip leading global flags: `kubectl -n ns
get pods` was rejected as verb "-n". firstVerb() now skips -n/--namespace/
--context/-o/etc. before validating, so read commands with global flags
work and mutating verbs behind a flag are still caught.
@mayankpande88
mayankpande88 requested a review from a team as a code owner June 12, 2026 05:46

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces the KUBECTL_ALLOW_WRITE configuration option (gated by runner.enableWritePermissions in the Helm chart) to lift the read-only restriction on the kubectl command executor. It also adds logic to parse the actual command verb past any leading global flags. The review feedback points out that several common global flags (such as -v and --v for verbosity) are missing from the verbFlagsWithValue map, which would cause the parser to incorrectly identify their values as the command verb. It is recommended to add these missing flags and include a test case to verify this behavior.

Comment thread runner/pkg/kube/exec.go
Comment thread runner/pkg/kube/exec_test.go
Address review: -v/--v (verbosity), --username/--password/--as-uid/
--vmodule also consume a following token. Without them, `kubectl -v 6
get pods` resolved "6" as the verb and failed validation.
@github-actions

Copy link
Copy Markdown
Contributor

📦 Image Tags Updated

I've automatically updated the image tags in `charts/nudgebee-agent/values.yaml` to the latest versions from GHCR for the `main` branch.

The image tags are now synchronized with the latest builds and ready for release.

@mayankpande88
mayankpande88 merged commit c641a9b into main Jun 12, 2026
8 checks passed
@mayankpande88
mayankpande88 deleted the feat/kubectl-write-mode branch June 12, 2026 05:57
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.

2 participants