Repository navigation
Add kubectl plugin - #681
Open
lbajsarowicz wants to merge 6 commits into
Open
lbajsarowicz wants to merge 6 commits into
lbajsarowicz wants to merge 6 commits into
Conversation
Tokenises the arguments kubectl receives: values of value-taking global flags are consumed, boolean flags follow pflag semantics with last-wins, underscores are normalised to dashes, shorthand clusters are split, and "--" ends option parsing only at an option boundary. Shapes the parser cannot resolve, such as a subcommand-local flag followed by a server override, are reported as ambiguous so the provisioner can decline.
Typed kubeconfig structs that round-trip through yaml.v2, a per-file reader with duplicate-name detection, a merger that follows kubectl's first-wins rules, strict normalisation of API server URLs for matching, and a converter that accepts PEM or base64-encoded PEM and checks the block type. Adds the Certificate Authority field name to the SDK.
Local-only commands (config, completion, options, plugin, kustomize, kuberc, help, shell completion hooks, version --client) and commands that pass their own credentials on the command line skip 1Password. Everything else, including external kubectl plugins, may contact the API server and needs the item.
…matching context Resolves the config sources and the target context the way kubectl does, and only when the target server matches the item's Address writes a temporary overlay that redefines that one context to use a per-invocation user carrying the item's token or client certificate. The overlay goes first in KUBECONFIG; the user's clusters, other contexts and current-context stay untouched. Impersonation fields are preserved. A kuberc file with aliases or connection-related defaults, an ambiguous command line, or explicit auth flags make the plugin step aside. On a machine with no kubeconfig at all the item alone produces a standalone config.
Reads the KUBECONFIG files, or ~/.kube/config, merges them as kubectl would and offers one item per context whose user holds a bearer token or a client certificate pair. Users authenticated through exec plugins, auth providers or a token file are left alone. Referenced certificate files are resolved relative to the file that names them and stored as base64; diagnostics name paths only.
lbajsarowicz
marked this pull request as ready for review
October 8, 2026 19:43
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Adds a
kubectlshell plugin, as requested in the community thread "Any plans for creating a kubectl (.kube/config) CLI plugin?".A kubeconfig can hold two kinds of static secrets: a bearer
token, or a client certificate with its private key (client-certificate-data/client-key-data). The plugin moves those into a 1Password item (Address, Token, Certificate, Private Key, Certificate Authority) and provides them to kubectl only for the context whose cluster matches the item's Address.How provisioning works: the plugin resolves the config sources the way kubectl does (
--kubeconfig, thenKUBECONFIG, then~/.kube/config), merges them with kubectl's first-wins rules, and resolves the target context and server (--context,--cluster,--server, thencurrent-context). When the server matches the item's Address, it writes a temporary kubeconfig overlay that redefines only that one context, pointing it at a per-invocation user that carries the item's secrets, and puts the overlay first inKUBECONFIG. Clusters, other contexts andcurrent-contextstay the user's own. When the server does not match, nothing is provisioned and kubectl behaves exactly as without the plugin, sokubectl config use-contextand--contextkeep working (this is the class of problem reported for Argo CD in #526). With--kubeconfig F, the flag is moved intoKUBECONFIG=<overlay>:F, the same approach the ngrok and aws plugins use to rewrite the command line. No secret ever appears in the command line.The importer reads the active kubeconfig set (
KUBECONFIGor~/.kube/config) and offers one item per context with a static secret. Users authenticated throughexecplugins orauth-provider(EKS, GKE, AKS, OIDC) have nothing to import and are left untouched;tokenFileusers are skipped as their token is usually rotated.Local-only commands (
config,completion,options,plugin,kustomize,kuberc,help,version --client, shell completion) do not require authentication.configin particular must never run with the overlay, becauseconfig set-*writes into the firstKUBECONFIGfile.Things worth a maintainer's opinion:
*-datafields; the provisioner also accepts raw PEM. If multi-line fields are well supported in items, PEM could become the canonical form.CertificateandPrivate Keyare reused for the client pair and one new field name,Certificate Authority, is added.Client Certificate/Client Keywould be the alternative.KUBECONFIG,KUBERNETES_SERVICE_HOST,KUBERNETES_MASTER), the item alone produces a standalone config for its cluster.defaults(server, context, cluster, user, auth, TLS, proxy) makes the plugin step aside, fail-closed, andKUBECTL_KUBERC=falseis not honoured, so kuberc is always treated as active; externalkubectl-*plugins are treated as needing the cluster; URL equality is the cluster identity, as in the Argo CD plugin.Type of change
Related Issue(s)
How To Test
Unit tests cover the parser, the kubeconfig loader and merge rules, server normalisation, the provisioner (context match and mismatch,
--kubeconfig, multi-fileKUBECONFIG, fresh machine, impersonation fields, kuberc), the importer and the needs-auth rule:go test ./plugins/kubectl/ -v make kubectl/validateWith the CLI, using an item whose Address is your cluster's
serverand a kubeconfig that also has a second, local context:op plugin init kubectlimports every context of~/.kube/config(or the files inKUBECONFIG) that carries a token or a client certificate pair.Verified end to end with 1Password CLI 2.40.0 and kubectl v1.37.1 against a Scaleway Kapsule cluster (Kubernetes 1.37): the token was imported from a kubeconfig obtained with
scw k8s kubeconfig get … auth-method=legacy,kubectl get pods,logsandexec -it … -- shauthenticate through the item, and the same commands against a local docker-desktop context are left untouched.Changelog
Authenticate kubectl with a token or client certificate stored in 1Password, provided only to the context that targets the item's cluster.