
Kubernetes has a long history of making the hard things possible and the dangerous things… also possible. Sometimes in the same feature.
On January 9, 2026, Kubernetes published a v1.35 blog post titled “Kubernetes v1.35: Restricting executables invoked by kubeconfigs via exec plugin allowList added to kuberc” by Peter Engelbert and Ben Petersen (both at Microsoft). citeturn4view0
The headline looks specific (it is), but the implication is broad: Kubernetes is adding a guardrail against one of the more quietly explosive realities of day-to-day cluster access—your kubeconfig can cause kubectl to execute local binaries.
With Kubernetes v1.35, SIG-Auth and SIG-CLI have introduced a credential plugin policy and allowlist that can be enforced via kuberc (kubectl user preferences). In short: you can now tell kubectl “don’t run any exec credential plugins” or “run only these specific ones.” citeturn4view0turn7view0
That’s not just a nice-to-have. It’s a pragmatic response to supply-chain risk, overly-trusting automation, and the reality that “it’s just a kubeconfig” has become a sentence that security teams hear right before something expensive happens.
Wait, kubeconfig can run executables?
Yes. And it’s not new—just newly treated with the seriousness it deserves.
Kubernetes clients (including kubectl) can authenticate using an exec credential plugin. In kubeconfig, that’s typically represented by a users[n].exec.command field (plus args/env), pointing to a program that will fetch or mint credentials on demand.
It’s extremely useful for modern identity flows (OIDC logins, cloud provider auth helpers, short-lived tokens). And it’s also, by definition, a mechanism that lets a configuration file cause code execution on your workstation with your privileges. The Kubernetes v1.35 blog post spells this out bluntly: kubectl can run arbitrary executables, including shell scripts, without you noticing. citeturn4view0
In other words: the authentication “plugin” is not a plugin in the safe browser-extension sense. It’s a local process invocation. If the command is malicious (or swapped, or tampered with), you’ve handed it the keys to your laptop—often a laptop that can reach production clusters, CI systems, internal Git repos, password managers, and the sort of Slack channels where people post “temporary” secrets.
Why this became a bigger problem in the cloud-native era
Exec plugins grew up in an era when Kubernetes access was moving away from long-lived client certificates and toward external identity providers. You can view this as progress (it is), but it also introduced a new trust chain:
- You trust the kubeconfig generator (your cloud provider, your platform team tooling, an onboarding script, a Terraform module, etc.).
- You trust the referenced binary (and the path resolution rules that decide which binary runs).
- You trust your workstation environment (PATH order, symlinks, filesystem integrity, malware resistance).
- You trust update mechanisms (auto-update CLIs, package managers, “curl | bash” installers—which are convenient right up until they aren’t).
This is why the v1.35 post frames the issue as a supply-chain and pipeline compromise risk: if the system that generates kubeconfigs is compromised, attackers can trick you into running arbitrary code by embedding a malicious exec command. citeturn4view0
And it’s not theoretical. The industry has had years of wake-up calls about build pipelines, signing chains, dependency hijacks, and credential theft. Kubernetes itself isn’t uniquely vulnerable here—any tool that executes local helpers based on configuration is a target. What’s different is how widely kubeconfigs get passed around, how casually they’re sometimes handled, and how much access they can represent.
Kuberc: from quality-of-life feature to security control surface
If you missed the earlier chapter: kuberc is a kubectl user preferences file. Think “gitconfig for kubectl,” but with fewer arguments about tabs vs spaces.
Kubernetes introduced kuberc as an alpha feature in v1.33, and brought it to beta in v1.34, letting users define aliases and default flags without mixing those preferences into kubeconfig. citeturn10search5turn10search0
By Kubernetes v1.35, kuberc’s scope expands: it can now include a Credential Plugin Policy section that controls whether exec plugins may run at all, and if so, which ones. citeturn7view0turn4view0
That separation matters. Kubeconfig is frequently generated or distributed; kuberc is personal policy. This is Kubernetes quietly saying: “Your cluster access file might be managed by someone else, but your workstation execution rules should be managed by you.”
The new Kubernetes v1.35 feature: credentialPluginPolicy and credentialPluginAllowlist
In v1.35, you can configure kubectl by adding two top-level fields to your kuberc file:
credentialPluginPolicycredentialPluginAllowlist
These restrict which credential plugins kubectl is allowed to execute. citeturn4view0turn7view0
Policy options: AllowAll, DenyAll, Allowlist
The policy field has three meaningful modes:
- AllowAll: no restrictions (this matches the “classic” behavior).
- DenyAll: no exec plugins may run.
- Allowlist: only explicitly allowed plugins may run (and you must define the allowlist).
The official kuberc documentation emphasizes that leaving the policy empty behaves like AllowAll for backward compatibility—so users don’t get surprised after upgrading. citeturn7view0
Here’s the minimal kuberc example that keeps the historical behavior:
apiVersion: kubectl.config.k8s.io/v1beta1
kind: Preference
# (no credentialPluginPolicy set)
And the explicit equivalent:
apiVersion: kubectl.config.k8s.io/v1beta1
kind: Preference
credentialPluginPolicy: AllowAll
Both are described in the v1.35 blog post. citeturn4view0
“DenyAll” as an inventory tool (and a mild chaos test)
If you’re not sure whether you rely on exec plugins, the Kubernetes blog recommends trying DenyAll. You’ll immediately see which plugin kubectl attempted to execute because authentication will fail with an error naming the plugin. citeturn4view0
Example:
apiVersion: kubectl.config.k8s.io/v1beta1
kind: Preference
credentialPluginPolicy: DenyAll
If you need more troubleshooting detail, you can increase kubectl verbosity (the blog suggests using higher verbosity to surface more context). citeturn4view0
Allowlist mode: safest practical option for most teams
Allowlisting is the sweet spot: it blocks unexpected executables but lets you keep working with the credential helpers you intentionally installed.
Example from the v1.35 blog post:
apiVersion: kubectl.config.k8s.io/v1beta1
kind: Preference
credentialPluginPolicy: Allowlist
credentialPluginAllowlist:
- name: /usr/local/bin/cloudco-login
- name: get-identity
Notice two patterns:
- One entry is a full path (more restrictive, preferred).
- One entry is a basename, resolved via PATH lookup rules (less restrictive).
The blog explicitly notes that wildcard/glob patterns aren’t supported, and basename resolution uses Go’s exec.LookPath. citeturn4view0
Important detail: symlinks and globs are not resolved
The kuberc documentation gets very specific—and security engineers will appreciate it. When determining whether a plugin is allowed, full path resolution does not resolve symlinks or shell globs. If you allowlist /usr/local/bin/my-binary but the kubeconfig references its symlink target directly, it won’t match unless you also allowlist that target path. citeturn7view0
This is a deliberate design choice that tends to reduce ambiguity (and therefore surprise) in security decisions.
Under the hood: it’s not just kubectl, it’s client-go
One of the more strategic aspects of this v1.35 change is that it’s not limited to kubectl.
The Kubernetes blog explains that SIG-Auth and SIG-CLI added the credential plugin policy and allowlist as a beta feature in 1.35, and that it’s available to all clients using the client-go library via the ExecProvider.PluginPolicy struct on a REST config. citeturn4view0
That matters because plenty of organizations have internal tooling built on client-go—custom deployment orchestrators, internal CLIs, cluster inventory tools, and scripts that quietly run with elevated access in CI/CD. If those tools load kubeconfigs and execute credential plugins, they can potentially benefit from the same policy controls—assuming they adopt the relevant configuration plumbing.
Threat modeling this feature: what it helps with (and what it can’t)
Let’s treat this as a security feature, not just “yet another YAML option.” What threat scenarios does it address?
1) A malicious or tampered kubeconfig
If someone gives you a kubeconfig file (downloaded from a portal, attached in a ticket, copied from a wiki, generated by a script), it can include an exec command. Without guardrails, kubectl will run it. With DenyAll or Allowlist, that surprise gets blocked.
This is especially relevant in contractor/consultant onboarding flows where kubeconfigs may be produced by automation that spans multiple teams.
2) PATH hijacking and “same name, different binary”
If you allowlist a basename (like get-identity), then PATH order decides what binary runs. That’s convenient, but also a classic attack surface: drop a malicious get-identity earlier in PATH, wait for kubectl to invoke it, profit.
The blog nudges users toward full paths for tighter scope. citeturn4view0
3) Supply-chain attacks against credential helper binaries
If a credential plugin itself is replaced (malicious update, compromised distribution channel), an allowlist won’t detect that—because you’re still allowlisting the same path/name.
The Kubernetes blog calls out future enhancements that could address this, including checksum verification (sha256) and signature verification against trusted keys. citeturn4view0
So today’s feature is a big step, but it’s primarily execution control (which program) rather than integrity verification (which exact build of that program).
4) “Ambient execution” and invisible privilege boundaries
Perhaps the biggest cultural improvement is simply visibility: it forces teams to acknowledge that authentication workflows involve local code execution. That can trigger better operational hygiene, like pinning versions, installing helpers through managed endpoints, or sandboxing developer workstations.
Practical rollout guidance for teams (without breaking everyone on Friday)
If you manage a platform team or security engineering program, the key is adopting this without turning Monday morning into a kubectl support queue.
Step 1: Inventory first with DenyAll (in a safe environment)
Start by trying DenyAll in a non-critical environment or on a subset of machines. The kubectl maintainers explicitly position DenyAll as a way to discover which plugins are being invoked. citeturn4view0turn7view0
Capture the errors, identify the binaries, and determine which are legitimate. Some organizations will be surprised how many different helpers show up across teams (cloud provider CLIs, SSO agents, internal wrappers, older legacy scripts).
Step 2: Move to Allowlist with full paths wherever possible
Prefer explicit paths like /usr/local/bin/... rather than basenames. This narrows the attack surface and reduces the role of PATH manipulation. citeturn4view0turn7view0
If your organization uses a device management platform, you can standardize installation paths for credential helpers, which makes allowlisting less painful.
Step 3: Document provider-specific requirements
The kuberc documentation includes a caution: if you’re using a managed Kubernetes provider, check the provider’s docs for which exec plugins are required, and use Allowlist accordingly. citeturn7view0
This is important because managed providers often ship authentication flows that depend on helper CLIs. Blocking them might “improve security” in the same way unplugging a router improves network security: yes, but also no.
Step 4: Treat kuberc as policy-as-code (light edition)
Even though kuberc is a user preference file, it’s now also a security policy. That suggests operational patterns:
- Provide a hardened baseline kuberc in your workstation setup scripts.
- Version it in an internal repo (and sign releases if you’re fancy).
- Teach developers how to extend it safely rather than disabling it when it blocks something.
Also note: kuberc can be pointed to a custom location via --kuberc or the KUBERC environment variable; the default is $HOME/.kube/kuberc on POSIX systems and a similar path under %USERPROFILE% on Windows. citeturn7view0
How this fits into Kubernetes’ broader security direction
Kubernetes security improvements often happen in a very Kubernetes-y way: incrementally, with careful backward compatibility, and via knobs that can be adopted progressively.
The credential plugin allowlist is part of a broader pattern:
- Moving risky defaults into explicit, user-controlled policies.
- Reducing implicit trust in configuration artifacts that come from automation pipelines.
- Providing hardening options that work for both individuals and large enterprises.
It’s also consistent with what security frameworks have been pushing for years: minimizing implicit trust, applying least privilege, and constraining execution paths. If your security strategy includes supply-chain hardening, this is an easy win because it requires no cluster change—only client-side configuration.
Concrete scenarios where this will save your bacon
Scenario A: “Here’s your kubeconfig, welcome aboard”
New engineer joins, downloads kubeconfig from an internal portal. The portal was compromised for 20 minutes (nobody noticed), and a malicious exec command was injected. Without policy controls, their first kubectl get ns triggers arbitrary code execution.
With DenyAll/Allowlist in kuberc, kubectl refuses to run that unexpected binary. The compromise becomes an authentication failure—not a workstation compromise.
Scenario B: Shared jump hosts and “helpful” PATH modifications
On shared bastion/jump environments, PATH changes happen constantly. Someone installs a “temporary” script named the same as a legitimate credential helper. If your allowlist uses basenames, you may unintentionally authorize the wrong binary.
Full-path allowlisting mitigates this; and the design’s lack of globbing keeps it from accidentally matching broader sets than intended. citeturn4view0turn7view0
Scenario C: Developer machines with multiple cloud CLIs and plugins
Many engineers today have AWS, Azure, and GCP tooling installed side by side, plus internal wrappers. Inventorying and then allowlisting forces an explicit decision about what you trust to run during cluster authentication. Even if you end up allowlisting several helpers, you’ve turned “anything goes” into “these known things go.”
What’s next: checksums, signatures, and a future with fewer surprises
The v1.35 blog post explicitly calls out potential future enhancements: allowlist entries could include requirements like sha256 checksums and/or signature verification against trusted signing keys. citeturn4view0
If Kubernetes evolves in that direction, it could bring exec credential plugins closer to a “trusted plugin” model rather than “whatever executable this path points to right now.” Until then, organizations that want integrity checks can layer controls via endpoint management, OS-level allowlisting (e.g., Windows AppLocker, macOS notarization controls), or internal distribution systems with strong signing and verification.
Quick FAQ for practitioners
Does this require a cluster upgrade?
No. This is a client-side behavior and policy. The blog emphasizes configuring kubectl via kuberc, and the underlying policy support is in Kubernetes v1.35 client tooling and client-go. citeturn4view0
Is it behind a feature gate?
The v1.35 blog post states the new features are in beta and available without using any feature gates. citeturn4view0
Where do I put kuberc?
Default location is $HOME/.kube/kuberc on Linux/POSIX and %USERPROFILE%\.kube\kuberc on Windows; you can override with --kuberc or the KUBERC env var. citeturn7view0
What if my team uses managed Kubernetes?
Expect to need at least one exec plugin, and follow your provider’s documentation. The kuberc docs caution that DenyAll may break managed provider auth flows and recommend switching to Allowlist once you identify the required plugin(s). citeturn7view0
Closing thoughts: Kubernetes is finally putting a seatbelt on a rocket-powered scooter
Kubernetes exec credential plugins are powerful—and power is always a security story waiting to be written. The v1.35 addition of credentialPluginPolicy and credentialPluginAllowlist in kuberc doesn’t remove the risk of running external helpers, but it gives you a crucial ability: control.
And in the modern supply-chain threat landscape, control is the difference between “we had an incident” and “we had an error message.”
Sources
- Kubernetes v1.35: Restricting executables invoked by kubeconfigs via exec plugin allowList added to kuberc (Peter Engelbert, Ben Petersen) citeturn4view0
- Kubectl user preferences (kuberc) — credential plugin policy and allowlist documentation citeturn7view0
- kuberc (v1beta1) API reference — fields and definitions citeturn8search2
- Kubernetes v1.34: User preferences (kuberc) are available for testing in kubectl 1.34 (Maciej Szulik) citeturn10search0
- Kubernetes 1.35 – New security features (Sysdig analysis/overview) citeturn8search3
Bas Dorland, Technology Journalist & Founder of dorland.org