Helm 3 Architecture (No Tiller)
Helm 3 is a client-only tool — it talks directly to the Kubernetes API and stores release state as Secrets in the cluster.
Helm 2 had a server-side component called Tiller that ran inside the cluster with broad permissions. It was a security and operations headache. Helm 3 removed Tiller entirely.
How Helm 3 works
The helm command is now a pure client. When you install a chart, Helm:
- Renders the chart templates locally into plain Kubernetes manifests.
- Sends those manifests straight to the Kubernetes API server using your kubeconfig credentials.
- Records the result — the release — as a
Secretin the target namespace.
Because it uses your own credentials, Helm respects Kubernetes RBAC just like kubectl does. There is no extra privileged component to secure.
Where release history lives
Each revision of a release is stored as a Secret (type helm.sh/release.v1) in the release's namespace. That is how Helm knows the history and can roll back.
Example
# Helm stores each release revision as a Secret in the namespace
kubectl get secret -n default -l owner=helm
# Example output:
# NAME TYPE DATA AGE
# sh.helm.release.v1.my-web.v1 helm.sh/release.v1 1 2mWhen to use it
- A security team audits a Kubernetes cluster and notes there is no Tiller pod running because the project uses Helm 3, reducing the attack surface compared to older Helm 2 setups.
- A platform engineer grants a service account only the RBAC permissions needed for Helm releases in one namespace, because Helm 3 uses the caller's kubeconfig credentials rather than a privileged in-cluster component.
- An SRE investigates a failed release by reading the release Secret stored in the target namespace, knowing Helm 3 persists state in Secrets rather than a separate server-side database.
More examples
View Helm release secrets
Lists the Kubernetes Secrets Helm 3 uses to store release history, replacing Helm 2 Tiller's ConfigMap-based storage.
kubectl get secrets -n my-namespace \
-l owner=helm \
--sort-by=.metadata.creationTimestampInspect release state data
Decodes the gzipped double-base64-encoded release Secret to read the metadata Helm stores about a release revision.
kubectl get secret sh.helm.release.v1.my-app.v1 \
-n my-namespace \
-o jsonpath='{.data.release}' \
| base64 -d | base64 -d | gunzip | jq .infoUse a dedicated kubeconfig
Demonstrates Helm 3 client-only design: it reads credentials from the active kubeconfig context and needs no in-cluster component.
export KUBECONFIG=~/.kube/staging-config
helm list -n my-namespace
helm upgrade my-app ./chart -n my-namespace
Discussion