What can a getter/v1 Helm plugin do that a cli/v1 plugin cannot?
answer
- The types differ by who invokes them
- One waits to be typed
- The other is triggered by a URL
- Transparent inside repo add and dependency update
- Credentials arrive through the environment
basics
~20 sA getter/v1 plugin registers URL schemes and is called by Helm during any fetch that uses one, so it works inside helm repo add, pull, install and dependency update. A cli/v1 plugin only adds a subcommand someone types.
solid answer
~50 sThe difference is who invokes the plugin. A `cli/v1` plugin declares a name and becomes a new top-level subcommand: it runs when a person or a script types `helm <name>`, and Helm's own commands never call it. A `getter/v1` plugin declares the URL schemes it serves, and Helm calls it from inside its download path whenever a chart reference, repository URL or dependency uses one of those schemes. That means a getter plugin is transparently in the path of `helm repo add`, `helm pull`, `helm install`, `helm upgrade` and `helm dependency update` without the user naming it at all. It receives the URL to fetch and returns the bytes — a chart archive or a repository index. Because credentials must reach it too, Helm passes repository credentials to a downloader through the environment, using `HELM_PLUGIN_USERNAME` and `HELM_PLUGIN_PASSWORD` rather than command-line arguments.
code
bash · 4 lineshelm plugin list
helm repo add internal myproto://charts.internal.example/stable
helm install api internal/api-chart --version 2.11.3
helm dependency update ./api-chartgo deeper
Know that Helm plugins come in more than one kind and that the type field in plugin.yaml decides which. Recognising cli/v1 as the subcommand kind is enough at this level.
Explain the distinction by caller: a cli/v1 plugin runs when someone types its name, a getter/v1 plugin runs when Helm needs a URL on a scheme it registered. Name the commands a getter transparently affects.
Discuss the operational consequence — a getter plugin sits invisibly in the fetch path of installs and dependency updates, so its failure looks like a repository outage, and its credential handling through the environment is part of your secret-exposure surface.
Weigh whether teaching Helm a bespoke scheme is worth the ongoing cost of a plugin every engineer and runner must install, against simply serving charts over a protocol Helm already speaks.
### Two extension points, two callers Helm 4 requires every plugin to declare a `type` in its `plugin.yaml`, and the type decides how the plugin is reached. This is the cleanest way to understand the plugin system: the types are not categories of function, they are categories of caller. **`cli/v1` — the user calls it.** The plugin declares a name, and Helm exposes that name as a top-level subcommand. Typing `helm values-lint ./values.yaml` finds the installed plugin called `values-lint` and executes it with the remaining arguments, plus Helm's environment (`HELM_BIN`, `HELM_NAMESPACE`, `HELM_PLUGIN_DIR`, `HELM_PLUGIN_NAME`, `HELM_PLUGINS`). The plugin's exit code becomes helm's exit code. Nothing inside Helm ever calls a CLI plugin on its own initiative; if nobody types the name, it never runs. **`getter/v1` — Helm calls it.** The plugin declares which URL schemes it serves. From then on, whenever Helm needs to fetch something and the URL uses one of those schemes, Helm hands the fetch to the plugin instead of to a built-in downloader. The plugin receives the URL and returns the bytes; Helm carries on as if it had downloaded them itself. ### Where a getter plugin sits in the path That second mechanism is worth dwelling on because it puts the plugin in places nobody thought to look: - `helm repo add myrepo <scheme>://…` — the repository index is fetched through the plugin. - `helm pull` and `helm install`/`helm upgrade` with a chart reference on that scheme — the chart archive comes through the plugin. - `helm dependency update` — a subchart whose `repository` field uses that scheme is resolved through the plugin. - `helm search repo` against a cached index that the plugin originally supplied. A `cli/v1` plugin can do none of this. It can of course fetch a chart itself and hand you a file, but it cannot make `helm install` understand a new scheme, because it is not in that code path. If your goal is *extend where Helm gets charts from*, only a getter plugin achieves it; if your goal is *add a new operation the team runs by hand*, only a CLI plugin makes sense. ### Credentials A downloader usually needs authentication, and Helm cannot simply hand it whatever the user typed, because credentials on a command line leak into process listings and shell history. Instead Helm passes repository credentials to the plugin through the environment: `HELM_PLUGIN_USERNAME` and `HELM_PLUGIN_PASSWORD` carry the username and password for the repository being fetched, and there is a related control governing whether those credentials are passed on across a redirect to a different host rather than being dropped. That last detail exists for a real reason — silently forwarding a repository credential to whatever host a redirect names is a credential-leak bug, so the safe behaviour is to drop it unless the operator opted in. ### The third type, for completeness The remaining type, `postrenderer/v1`, is a third caller again: Helm invokes it after rendering, when `--post-renderer` names it. The mechanics of what a post-render step may do to the manifest stream belong with the post-renderer material, not here; the point for this question is only that the `type` field is what routes a plugin to the right caller, and that Helm 4 requires it precisely so the routing is explicit rather than inferred from which blocks happen to be present in the descriptor. ### How to answer this in an interview The short, complete answer names the caller: a CLI plugin is invoked by a person typing its name, a getter plugin is invoked by Helm during a fetch, on the strength of a URL scheme. Everything else — the commands a getter transparently affects, the credential environment variables, the inability of a CLI plugin to teach `helm install` a new scheme — follows from that one distinction. Candidates who have only ever installed a diff plugin usually assume all plugins are subcommands, and this is the question that surfaces it.
- Why does Helm hand repository credentials to a downloader plugin through environment variables rather than arguments?Command-line arguments are visible in process listings and land in shell history and CI logs, so a password passed that way leaks well beyond the intended process. Helm sets HELM_PLUGIN_USERNAME and HELM_PLUGIN_PASSWORD in the plugin's environment instead. There is also a deliberate rule about redirects: credentials are not forwarded to a different host unless that has been explicitly allowed, because silently following a redirect with a repository credential attached hands it to whoever controls the redirect target.
- Could you get the same effect as a getter plugin by wrapping helm in a shell script?Only for the commands you wrap, and only where people use your wrapper. A getter plugin is registered inside Helm, so it also covers indirect fetches you did not think about — a subchart resolved by helm dependency update, a repository index refreshed during a search. A wrapper also has to be adopted by every engineer and every pipeline to be effective, whereas the plugin works for anyone who has it installed, whatever entry point they use.
A CLI plugin is a new tool in the drawer, useful only when someone reaches for it. A getter plugin is a new adapter wired into the wall, so anything that plugs in that shape works without knowing the adapter is there.
saying these in an interview costs you the question
- Assumes every plugin is a helm subcommand
- Thinks a CLI plugin can teach helm install a new URL scheme
- Says the type field is only documentation
- Believes a getter plugin must be invoked by name
- Would pass repository passwords as plugin arguments