---
title: "Install a Kubernetes Dashboard with Helm (Token Auth + TLS) | CloudGuys Blog"
description: "Install a Kubernetes dashboard with Helm the safe way: token auth by default, loopback first, then Ingress with TLS and a license key for writes."
url: "https://cloudguys.io/blog/install-kubernetes-dashboard-helm-token-auth-ingress-tls"
language: "en"
image: "https://cloudguys.io/_astro/cover-cloudguys.DQp1lTsL.jpg"
published: "2026-09-15T00:00:00.000Z"
modified: "2026-09-15T00:00:00.000Z"
---

ENGINEERING NOTES / BERTH

# Install a Kubernetes Dashboard with Helm: Token Auth, Ingress, and TLS

A safe, end-to-end guide to installing the Berth Kubernetes dashboard with Helm: token auth, loopback access, Ingress, TLS, and license keys.

Agrohi Team · · · September 15, 2026 · · · 9 min read

![Install a Kubernetes Dashboard with Helm: Token Auth, Ingress, and TLS](https://cloudguys.io/_astro/cover-cloudguys.DQp1lTsL_Z19xgEM.webp)

Most Kubernetes dashboard installs go wrong in the same two places. The first is authentication: you apply a manifest, then spend twenty minutes creating a ServiceAccount, binding a ClusterRole, and pulling a bearer token out of a Secret before the login screen will let you in. The second is exposure: the dashboard works on `localhost`, someone wants it reachable from a browser, and it ends up behind a plain HTTP address with weak or no auth on a tool that can read and change the whole cluster.

This guide walks a safe path from nothing to a dashboard you can reach from a browser over HTTPS. It uses [Berth](https://cloudguys.io/blog/introducing-berth-self-hosted-kubernetes-dashboard-ai-sre), a self-hosted Kubernetes dashboard that ships as one container: a Vue single-page app embedded in a small Go binary. The chart defaults to token authentication and generates the token for you, so the first login is not a scavenger hunt.

The order matters. We install, reach the UI over a loopback port-forward, confirm it works, and only then expose it publicly with Ingress and TLS. Every step below has a short note on why it is the safe default, because the whole point of a dashboard is convenience and the whole risk of a dashboard is that convenience pointed at your cluster.

## Prerequisites

You need three things before you start:

-   **Helm 3.8 or newer.** The chart is published as an OCI artifact on GitHub Container Registry, and OCI support in Helm went stable in 3.8. Check with `helm version`.
-   **A running cluster and a `kubectl` context pointed at it.** Confirm with `kubectl config current-context` and `kubectl get nodes`. A disposable test cluster (kind, k3d, or a throwaway managed cluster) is a good place to run this the first time.
-   **A clear understanding of what you are installing.** Berth runs in-cluster with a ServiceAccount that has cluster-wide access. Dashboard access is cluster access. Everyone who can log in shares the pod’s ServiceAccount permissions, so treat the dashboard credential exactly as you would treat a kubeconfig with the same reach.

That last point drives every decision that follows. There is no per-user RBAC, no SSO or OIDC, and no multi-cluster view in Berth today. Those are on the roadmap, not in the current release, so plan access around a small group of trusted cluster administrators rather than a broad audience.

## Install with the OCI chart

The install is a single command. It creates the `berth` namespace, deploys the latest stable release, defaults to token authentication, and generates a token for you.

```sh
helm upgrade --install berth oci://ghcr.io/unishsys/charts/berth \
  --namespace berth --create-namespace
```

`helm upgrade --install` is idempotent: the same command installs the release the first time and upgrades it on every run after that, which keeps your install reproducible in a script or a CI job.

For production, pin the version instead of tracking latest, so an upgrade is a deliberate change to a value you control rather than a surprise on the next apply:

```sh
helm upgrade --install berth oci://ghcr.io/unishsys/charts/berth \
  --version 1.0.1 --namespace berth --create-namespace
```

Give it a moment to pull the image and become ready:

```sh
kubectl -n berth rollout status deploy/berth
```

The container image is `ghcr.io/unishsys/berth`. The deployment runs a single replica by design, since Berth uses single-writer storage; higher replica counts are rejected rather than silently accepted.

## Read the auth token and port-forward to reach the UI

The chart generated a token and stored it in a Secret named `berth-secrets`. Read it back and decode it:

```sh
kubectl -n berth get secret berth-secrets -o jsonpath='{.data.AUTH_TOKEN}' | base64 -d ; echo
```

Now reach the UI over a loopback port-forward. This binds the service to `127.0.0.1` on your machine and does not expose anything to the network:

```sh
kubectl -n berth port-forward svc/berth 8081:8081
```

Open `http://localhost:8081/` and paste the token when prompted.

Starting on loopback is deliberate. Before the dashboard is reachable by anyone else, you have confirmed the install works, seen the login screen, and verified the token. The port-forward tunnels through the Kubernetes API server and is authenticated by your kubeconfig, so nothing is listening on a public address yet. Public exposure is a separate, explicit step later, once you have decided how to secure it.

## Explore without a license key

You do not need a license key to look around. Viewing is always free, with no key of any kind. Log in with the token and you can browse nodes, pods, deployments, and services, stream pod logs live, read events inline, and see the cluster overview with endpoint health and per-node-pool capacity.

The gate is on writes, not reads. Creating, editing, or deleting resources requires a license. This split is useful on its own: you can install Berth on a cluster, hand a read-only view to the team, and never apply a key if all you want is observability. The dashboard stays fully readable regardless of license state or node count.

When you are ready to make changes from the UI, apply a key.

## Get and apply a Community key

A **Community** key is free, covers up to 10 nodes, and is scoped to a single cluster. Get one by creating an account at [berth.agrohi.com](https://berth.agrohi.com/); a Community key is issued to you automatically, and your current key is always available on your dashboard there. If you need more than 10 nodes or an unlimited-node allowance, the **Enterprise** tier has a 14-day trial. Pricing is at [berth.agrohi.com/pricing/](https://berth.agrohi.com/pricing/).

There are two ways to apply the key, and the right one depends on how you manage the cluster.

For a quick start, set it inline. `--reuse-values` keeps everything the previous install decided (including your generated auth token) and changes only the license:

```sh
helm upgrade --install berth oci://ghcr.io/unishsys/charts/berth --reuse-values \
  --set license.key='<YOUR_KEY>'
```

For GitOps, do not put the key in a values file that lands in Git. Create a Secret out of band (or with your secret manager), then point the chart at it. The Secret needs a `LICENSE_KEY` key:

```sh
helm upgrade --install berth oci://ghcr.io/unishsys/charts/berth --reuse-values \
  --set license.existingSecret=my-license
```

`existingSecret` is the pattern to prefer when the Helm values are committed to a repository, because the key material lives in a Secret you manage separately and rotate on its own schedule. To rotate, update the Secret and restart the pod; nothing in your tracked values changes.

One reassuring detail about how the license is checked: keys are Ed25519-signed and verified offline against a public key embedded in the binary. There is no phone-home, so verification works in an air-gapped cluster and Berth never calls out to validate your license. The current tier, trial countdown, and node usage show up in the dashboard’s license banner.

## Expose it publicly with Ingress and TLS

Once the install is confirmed on loopback and you have decided who should reach it, expose the UI through an Ingress with TLS. This example uses the NGINX ingress class and a TLS Secret named `berth-tls`:

```sh
helm upgrade --install berth oci://ghcr.io/unishsys/charts/berth --reuse-values \
  --set ingress.enabled=true --set ingress.className=nginx \
  --set ingress.host=berth.example.com \
  --set ingress.tls.enabled=true --set ingress.tls.secretName=berth-tls
```

Replace `berth.example.com` with your own hostname and make sure `berth-tls` holds a certificate for it (cert-manager is a common way to provision one). Point DNS for that hostname at your ingress controller.

Serve the dashboard over HTTPS, not plain HTTP. The token is a bearer credential: anything that can read it in transit can act on the cluster with the pod’s full permissions. TLS is what keeps that token off the wire in clear text.

Do not disable authentication on a cluster that is shared or reachable from a network. Berth supports an `auth.mode=none` setting for a strictly loopback-only local session, but on an exposed or shared cluster it removes the only thing standing between the open internet and cluster-wide access. Keep token auth on for anything with an Ingress.

Because every authenticated user shares one ServiceAccount, exposing the dashboard widely is the same as widening cluster access. Keep the audience to trusted cluster administrators, and reach for network controls (an internal load balancer, an allowlist, or a NetworkPolicy limiting inbound traffic to the ingress controller) when you want to narrow who can even reach the login page. If you want help designing that access model, our [Kubernetes consulting service](https://cloudguys.io/services/kubernetes-consulting) covers exactly this kind of hardening.

## Upgrade and pin versions

Upgrades use the same `helm upgrade --install` command. To move to a new version deliberately, change the pinned value:

```sh
helm upgrade --install berth oci://ghcr.io/unishsys/charts/berth \
  --version 1.0.1 --reuse-values --namespace berth
```

Pinning `--version` is the recommended practice for production. It makes every upgrade a reviewed change to a number in your chart values rather than whatever happened to be latest when the job ran, and it lets you roll forward and back on purpose.

Pre-releases are opt-in and never resolve automatically. A beta or other pre-release must be requested by its exact version:

```sh
helm upgrade --install berth oci://ghcr.io/unishsys/charts/berth \
  --version 1.0.0-beta --namespace berth --create-namespace
```

You will not receive a pre-release from the plain latest install or from a stable pin. You get one only when you name it, which keeps unstable builds out of clusters that did not ask for them.

## Uninstall cleanly

Removing Berth is a standard Helm uninstall. There is no separate Berth uninstall command:

```sh
helm uninstall berth -n berth
```

That removes the release and its objects, including the generated `berth-secrets`. The namespace itself remains. If you want it gone too, delete it once the release is removed:

```sh
kubectl delete namespace berth
```

If you applied a license through an `existingSecret` you created yourself, remember that Helm did not create it and will not remove it. Delete that Secret separately if it is no longer needed.

## Where to go next

You now have a Kubernetes dashboard installed with Helm, reached first over a safe loopback port-forward, gated behind token auth, exposed over HTTPS through an Ingress, and licensed for writes with a key you can rotate through a Secret. That is the full, safe path, and it is a handful of commands rather than an afternoon of RBAC plumbing.

If you want the background on what Berth is and why an operations consultancy built it, start with [Introducing Berth](https://cloudguys.io/blog/introducing-berth-self-hosted-kubernetes-dashboard-ai-sre). If you are curious about the built-in assistant that reasons over your live cluster without being able to change it, read [how Berth’s read-only AI SRE works](https://cloudguys.io/blog/read-only-ai-sre-kubernetes-how-it-works).

Ready to try it on your own cluster? [Create a free account and get a Community key](https://berth.agrohi.com/?utm_source=agrohi_blog&utm_medium=referral&utm_campaign=install-kubernetes-dashboard-helm), then run the one install command above. Viewing costs nothing and needs no key, so you can see your cluster in the dashboard before you decide anything else.

#Berth · #Kubernetes · #Helm · #Dashboard · #TLS

SEE IT ON YOUR OWN CLUSTER

## Berth: a Kubernetes dashboard  
you run yourself.

Endpoint health, capacity planning, and a read-only AI SRE. Free for small clusters, no phone-home. Discuss your Kubernetes security and architecture with CloudGuys.

[Get a free Community key ↗](https://berth.agrohi.com/?utm_source=agrohi_blog&utm_medium=referral&utm_campaign=install-kubernetes-dashboard-helm-token-auth-ingress-tls) [Talk to CloudGuys ↗](https://cloudguys.io/#architecture-review)

## Structured data

```json
[
  {
    "@context": "https://schema.org",
    "@type": "Organization",
    "@id": "https://cloudguys.io/#organization",
    "name": "CloudGuys",
    "url": "https://cloudguys.io/",
    "logo": {
      "@type": "ImageObject",
      "url": "https://cloudguys.io/assets/logo.png",
      "width": 512,
      "height": 512
    },
    "image": "https://cloudguys.io/assets/og-image.png",
    "description": "Security assessments, cloud architecture reviews, and practical remediation across AWS, Google Cloud, Azure, Kubernetes, and infrastructure as code.",
    "email": "hello@agrohi.com",
    "slogan": "Know your risks. Build a stronger cloud.",
    "areaServed": "Worldwide",
    "knowsAbout": [
      "DevOps",
      "Kubernetes",
      "Terraform",
      "Cloud migration",
      "Cloud cost optimization",
      "GitOps",
      "Site reliability engineering",
      "Kubernetes dashboard",
      "AI SRE",
      "Kubernetes troubleshooting",
      "AWS",
      "Google Cloud",
      "Azure"
    ],
    "contactPoint": {
      "@type": "ContactPoint",
      "contactType": "sales",
      "email": "hello@agrohi.com",
      "availableLanguage": [
        "English"
      ],
      "areaServed": "Worldwide"
    },
    "sameAs": [
      "https://www.linkedin.com/company/agrohitech",
      "https://berth.agrohi.com"
    ],
    "owns": {
      "@type": "SoftwareApplication",
      "@id": "https://berth.agrohi.com/#software",
      "name": "Berth",
      "applicationCategory": "DeveloperApplication",
      "operatingSystem": "Kubernetes",
      "url": "https://berth.agrohi.com",
      "description": "Berth is a self-hosted Kubernetes dashboard with a read-only AI SRE: endpoint health, capacity planning, guided app exposure, and evidence-based troubleshooting, run in your own cluster."
    }
  },
  {
    "@context": "https://schema.org",
    "@type": "WebSite",
    "@id": "https://cloudguys.io/#website",
    "url": "https://cloudguys.io/",
    "name": "CloudGuys",
    "description": "Security and cloud consultancy helping organizations assess risks, improve architecture, and verify remediation.",
    "publisher": {
      "@id": "https://cloudguys.io/#organization"
    },
    "inLanguage": "en"
  },
  {
    "@context": "https://schema.org",
    "@type": "BlogPosting",
    "@id": "https://cloudguys.io/blog/install-kubernetes-dashboard-helm-token-auth-ingress-tls#article",
    "headline": "Install a Kubernetes Dashboard with Helm: Token Auth, Ingress, and TLS",
    "description": "Install a Kubernetes dashboard with Helm the safe way: token auth by default, loopback first, then Ingress with TLS and a license key for writes.",
    "image": "https://cloudguys.io/_astro/cover-cloudguys.DQp1lTsL.jpg",
    "datePublished": "2026-09-15T00:00:00.000Z",
    "dateModified": "2026-09-15T00:00:00.000Z",
    "author": {
      "@type": "Organization",
      "name": "Agrohi Team",
      "url": "https://cloudguys.io/"
    },
    "publisher": {
      "@id": "https://cloudguys.io/#organization"
    },
    "mainEntityOfPage": {
      "@type": "WebPage",
      "@id": "https://cloudguys.io/blog/install-kubernetes-dashboard-helm-token-auth-ingress-tls"
    },
    "articleSection": "Berth",
    "keywords": "Berth, Kubernetes, Helm, Dashboard, TLS",
    "inLanguage": "en",
    "about": {
      "@type": "SoftwareApplication",
      "@id": "https://berth.agrohi.com/#software",
      "name": "Berth",
      "url": "https://berth.agrohi.com"
    }
  },
  {
    "@context": "https://schema.org",
    "@type": "BreadcrumbList",
    "itemListElement": [
      {
        "@type": "ListItem",
        "position": 1,
        "name": "Home",
        "item": "https://cloudguys.io/"
      },
      {
        "@type": "ListItem",
        "position": 2,
        "name": "Blog",
        "item": "https://cloudguys.io/blog"
      },
      {
        "@type": "ListItem",
        "position": 3,
        "name": "Install a Kubernetes Dashboard with Helm: Token Auth, Ingress, and TLS",
        "item": "https://cloudguys.io/blog/install-kubernetes-dashboard-helm-token-auth-ingress-tls"
      }
    ]
  }
]
```
