Helm 3 removes Tiller and uses the caller's Kubernetes identity
Helm 3.0.0 changes release management by removing its in-cluster server. Kubernetes authorization now applies through the caller's configuration, while release storage and patch generation remain important parts of the operational model.
Tiller solved a real coordination problem in Helm 2. Multiple operators working in a shared cluster needed access to the same releases, and an in-cluster component supplied the common release-management point. It also introduced a separate security problem once Kubernetes RBAC became the expected environment. The Helm 3.0.0 release on November 13 removes Tiller, moving chart rendering and release operations into a client that uses Kubernetes directly.
The change matters because the identity requesting an installation can now be the identity Kubernetes authorizes for its operations. Helm still records releases in the cluster. Removing Tiller changes how work is performed and authorized without making the client the only place that knows what was installed. The API server remains the shared system through which operators obtain release information.
I prefer this alignment with Kubernetes' existing authorization model. Its API is already the place where declared objects become operations subject to access control. A packaging tool can use that relationship directly, with the administrator defining what its caller may do in the cluster.
Why the shared server became unnecessary
Matt Fisher's April explanation of Tiller's removal describes the original tradeoff. Helm offered permissive defaults to make initial experimentation easy across many possible security policies. In a production or multi-tenant environment, those defaults could grant access broader than intended. Operators then needed additional work to lock down the component performing release operations.
The maintainers concluded that a central in-cluster operator was not required to preserve shared release management. Instead, a client could fetch information from the Kubernetes API, render charts locally and record the resulting installation in Kubernetes. Shared state could remain where Kubernetes stores it, while the executable performing the operation could run as the initiating user.
This is a useful architectural distinction. Shared information requires common storage and an access path, but it does not necessarily require a separate application server interposed before the API server. Helm 3 removes that additional component from its own release-management design. The authorization associated with a user's kubeconfig determines the permissions available for the operation.
Removing Tiller does not mean a chart can install anything its author names. The caller still needs the Kubernetes permissions required by the resources and operations involved. A chart is a packaging unit, while the API server evaluates operations against its authorization policy. The simplification is that these permissions belong to the caller's Kubernetes identity through the configured client connection.
Release information stays in the cluster
The Helm 3.0.0 action configuration selects a Kubernetes-backed release store. Its default driver uses Secrets in the configured namespace. A ConfigMap driver is also available. This makes the release record an explicit part of the new implementation rather than something lost when the central server disappears.
The namespace matters to how releases are found. The May release-management preview explains the move of release data into the release's destination namespace. A release name can consequently be used in different namespaces. The preview contrasts this with Helm 2's release revisions being stored together in Tiller's namespace, where the same release name could not be reused in that arrangement.
Some implementation details in an early preview can describe work in progress. For the released behavior, the tagged source confirms the namespace-scoped Secret store. That is the important boundary for understanding the data's location and the client configuration needed to access it. The release record remains Kubernetes data even though Tiller is absent.
Secrets as a storage mechanism also make authorization over that data relevant. Permissions to install application resources and permissions to read the packaging system's release records are parts of the actual operation. A model based on the caller's identity makes those requirements visible through Kubernetes access control, instead of treating the packaging client as an independent source of authority.
Patch generation considers the live object
Another consequential change appears in the Kubernetes client code tagged for Helm 3.0.0. The patch-generation function serializes the previous configuration and the new target, then fetches the current object from the server. For supported typed objects, it uses all three when creating a strategic merge patch.
The live object can differ from both chart representations. Another controller may have added information, or an operator may have changed a field after installation. A comparison restricted to the two chart manifests cannot describe that difference. Fetching the live resource gives patch generation information about what is actually present when the operation runs.
The distinction is especially relevant to Kubernetes installations that use admission integrations. A workload object may contain an injected container that never appeared in the chart template. The new patch-generation path can account for live configuration when producing its change. This is a mechanism in the released implementation, rather than an assumption that the chart's last rendered manifest describes the entire current object.
There is a specific limitation in the same function. When the versioned object is unstructured, the code falls back to a generic JSON merge patch constructed from the old and new data. Its comment identifies CRDs as an example for which strategic merge is not supported. The three-way strategic merge behavior should therefore not be generalized to every object that can appear in a chart.
That branch matters for extension-heavy clusters. Helm can package different Kubernetes resource types, but their update mechanisms are not necessarily identical. A custom resource does not acquire the patch metadata of a built-in typed object merely because both were rendered from templates in one release. Understanding the update requires knowing which path the client uses for the target object.
I consider this implementation detail more useful than a general promise that upgrades are safer. It identifies the data used to build a patch and the class of objects that take a different path. Those are concrete facts for evaluating interaction with the controllers that also modify a resource.
The client source also handles the case where patch generation produces no change. An empty patch causes it to refresh resource information from the server before returning. Its comment explains that labels and other information still need to be available to later operations. Even an update that sends no patch can therefore require access to the current object.
At the broader update level, the client describes creating resources absent from the old list, updating modified targets and deleting resources no longer present in the target configuration. It returns information about attempted operations even when an error occurs. This is a set of Kubernetes operations with possible partial progress, which helps explain why release management still needs records and error handling after the central server is removed.
Familiar commands sit on the changed implementation
The release announcement demonstrates installing a named chart and removing it with helm uninstall. It also shows helm template as a way to inspect rendered output and helm create for producing a chart to edit. The packaging workflow remains recognizable even though the component that used to perform server-side work is gone.
For an existing local chart named application, these commands illustrate rendering and installation as separate operations. The installation targets an explicit example context and namespace. The chart and destination namespace must already be suitable for that installation.
helm template example ./application
helm install example ./application --kube-context example-cluster --namespace example
Rendering helps expose the Kubernetes objects a chart generates. Installation then performs operations using the caller's configuration. The separation makes chart output available for inspection without implying that rendering proves the caller is authorized to create every object. Kubernetes determines that authorization during the interaction with its API.
The major release also contains incompatible changes, which the announcement explicitly identifies. Experimental OCI registry support is among its additions, with further improvements listed as planned work. Its experimental status should remain separate from the stable 3.0.0 release itself. A stable CLI can contain an opt-in capability that has a different maturity expectation.
Helm's Go SDK has also been refactored for broader reuse, according to the announcement. The client architecture can therefore matter to programs integrating release management as well as to people invoking the command. For both uses, the released design removes Tiller while retaining cluster-backed release records and resource-specific patch behavior. The resulting permissions are those available to the Kubernetes client carrying out the operation.