Skip to content

Add exec credential plugin policy (kuberc credentialPluginPolicy parity) - #3109

Draft
brendandburns with Copilot wants to merge 1 commit into
mainfrom
copilot/implement-exec-credential-policy
Draft

brendandburns with Copilot wants to merge 1 commit into
mainfrom
copilot/implement-exec-credential-policy

Conversation

Copilot AI commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

Kubeconfig exec credential plugins start local processes. This PR lets applications restrict which plugins can run, using the same rules as kubectl's kuberc credential plugin policy. It ports kubernetes-client/csharp#1930. The default stays AllowAll, so existing behaviour doesn't change.

const kc = new KubeConfig();
kc.loadFromDefault();

kc.setExecCredentialPluginPolicy({
    credentialPluginPolicy: 'Allowlist',
    credentialPluginAllowlist: [{ command: 'kubelogin' }, { command: '/usr/local/bin/my-plugin' }],
});
// or: kc.loadExecCredentialPluginPolicyFromKuberc();   // $KUBERC → ~/.kube/kuberc

Changes

  • src/exec_credential_policy.ts (new)
    • Policy types use the same field names as kuberc: credentialPluginPolicy, credentialPluginAllowlist[].command, and the deprecated name alias.
    • validateExecCredentialPluginPolicy follows client-go's ValidatePluginPolicy. These are errors:
      • an unknown policy value
      • an allowlist set when the policy isn't Allowlist
      • a missing or empty allowlist
      • an empty entry, or one that sets both name and command
      • a path that isn't already normalized (e.g. ./foo)
    • checkExecCredentialPluginPolicy follows client-go's checkAllowlistLocked. A plugin is allowed if its command exactly matches an entry, or if both resolve through PATH to the same executable. Symlinks and globs are not resolved. Relative PATH entries are ignored.
    • Blocked plugins throw ExecCredentialPluginDeniedError.
    • parseKubercExecCredentialPluginPolicy reads only the policy fields from a kuberc file (kubectl.config.k8s.io/v1beta1 or v1, kind Preference) and ignores everything else.
  • ExecAuth
    • Takes the policy in its constructor or via setPolicy(). It is checked before any process starts, on the first call and on every token refresh.
    • Changing the policy clears cached tokens.
    • In Allowlist mode the resolved full path is executed. Node's spawn uses options.env.PATH for lookup, so without this a kubeconfig env: PATH=... could swap in a different binary with an allowlisted name. Go's exec.Command resolves against the parent's PATH, so this matches its behaviour.
  • KubeConfig
    • setExecCredentialPluginPolicy(policy?)
    • loadExecCredentialPluginPolicyFromKuberc(file?):
      • Looks up the file the way kubectl does: the file argument, then $KUBERC, then ~/.kube/kuberc.
      • Skips loading when KUBERC=off or KUBECTL_KUBERC=false.
      • A missing default file is fine; a missing explicitly named file (argument or $KUBERC) is an error.
      • Nothing loads the kuberc file automatically; the application has to call this.
  • Exports and docs: the new types and helpers are exported from index.ts, and the README has a new section.

Review notes

  • Environment variables (differs from the C# port): C# rejects every environment variable from the kubeconfig in Allowlist mode. kubectl doesn't, so this PR doesn't either. A kubeconfig PATH can't change which binary runs (see above), but other variables such as LD_PRELOAD still reach the plugin, as they do in kubectl. Rejecting them would be stricter but would break parity with kubectl.
  • Unresolvable commands: in Allowlist mode a command that can't be found on PATH is refused before spawning, even if its name is listed. kubectl also fails here, just later when it runs the command. Refusing early stops a kubeconfig-supplied PATH from being used for the lookup.
  • Scope: only exec plugins are covered, including the authProvider.config.exec form. The cmd-path options of the Azure and GCP auth providers are not, which matches kubectl.

@kubernetes-prow kubernetes-prow Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Oct 19, 2026
@kubernetes-prow
kubernetes-prow Bot requested a review from cjihrig October 19, 2026 17:09
@kubernetes-prow

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Copilot
Once this PR has been reviewed and has the lgtm label, please ask for approval from brendandburns. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubernetes-prow
kubernetes-prow Bot requested a review from davidgamero October 19, 2026 17:09
@linux-foundation-easycla

Copy link
Copy Markdown

CLA Not Signed

@kubernetes-prow kubernetes-prow Bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. labels Oct 19, 2026

This branch has not been deployed

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

Labels

cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants