Skip to main content
KubeStacks never gives anyone more than their own permissions: every request reaches the API server as the person who made it, and the API server applies their RBAC. What KubeStacks itself is trusted with depends on how people sign in.

Impersonation

With single sign-on that doesn’t pass people’s own tokens on, or behind a proxy, KubeStacks’ service account may impersonate anyone. Whoever can exec into its pod, or read its service account’s token, can then act as anyone in the cluster. Treat KubeStacks like any other component with cluster-wide power:
  • Keep it in a namespace of its own, one only cluster administrators can exec into, read Secrets in, or change workloads in.
  • Use prefixes (auth.usernamePrefix and auth.groupsPrefix), so no name or group from a provider or proxy is one of yours by accident.
  • Behind a proxy, let nothing else reach KubeStacks. It trusts the proxy’s headers completely. Turn on networkPolicy with the proxy’s pods in from.
KubeStacks never acts as one of Kubernetes’ own users or groups (system:…), whatever a provider or proxy says. It leaves out groups that start with system:, and refuses users whose names (with their prefix) do. When the API server trusts your provider, pass people’s tokens on instead: KubeStacks then needs no permissions at all.

Sessions and cookies

  • The browser holds only a random ID, 32 bytes, in the kubestacks-session cookie. It’s HttpOnly, SameSite=Lax, and Secure when url starts with https: or the proxy in front sends X-Forwarded-Proto: https.
  • Sessions live in KubeStacks’ memory. Restarting it signs everyone out, and nothing about them is written to disk. For the same reason the chart runs one replica.
  • Sessions last 12 hours unless auth.sessionHours says otherwise, at most a week. People signing out end their session in every tab.
  • Single sign-on uses the authorization code flow with PKCE. The state, PKCE verifier and nonce stay in a short-lived cookie, signed by KubeStacks, for at most 10 minutes. The ID token’s signature is checked against the provider’s keys, and its issuer, audience and nonce against what KubeStacks expects.
  • Only KubeStacks’ own pages can sign in with a token, sign out, or connect. Those requests, and the WebSocket, must come from KubeStacks’ own origin.

The page

Pages are served with a strict Content Security Policy (scripts only from KubeStacks itself, no frames, no plugins), and with headers that keep them out of other sites’ frames (X-Frame-Options: DENY), stop content-type sniffing, and send no referrers.

Charts and private networks

People choose where charts come from when they install or upgrade a Helm release, and KubeStacks fetches them from inside the cluster’s network, where it can reach services they can’t, and cloud metadata endpoints. So it fetches charts only from public addresses. A repository, registry or chart URL whose host is, or resolves to, a private address is refused: If your charts live in your own network, such as a ChartMuseum or Harbor, allow private addresses with helm.allowPrivateCharts: true. Anyone signed in can then make KubeStacks reach services inside the cluster’s network. Charts never come from files: there’s no computer of the user’s to read them from.

Read-only

  • readOnly: true keeps everyone from changing anything through KubeStacks, whatever their permissions.
  • Each person can also make KubeStacks read-only for themselves, in their own browser.
KubeStacks’ server enforces it, not only the page: it refuses changes, shells and Helm changes while it’s on. See Read-only mode.

The pod

The chart runs KubeStacks with these defaults, which you can tighten further but shouldn’t need to loosen:
Chart defaults
The image has Node.js, helm and KubeStacks, no shell, and runs as a non-root user. It writes only to /tmp, an emptyDir: helm’s caches, and for each run of helm a kubeconfig that acts as the person who asked (readable only by KubeStacks, and removed after). Each image is signed with a build provenance attestation; see Verify the image.

Hardening checklist

Pick token sign-in, or single sign-on with tokens passed on, when you can: KubeStacks then needs no permissions.
Run KubeStacks in its own namespace, which only cluster administrators can exec into or read Secrets in.
Set auth.usernamePrefix and auth.groupsPrefix when KubeStacks impersonates people.
Behind a proxy, turn on networkPolicy and name only the proxy in from.
Serve it over HTTPS, and set url to the https: address, so cookies are sent over HTTPS only.
Leave helm.allowPrivateCharts off unless your charts are in your own network.
Consider readOnly: true for a dashboard people should only look at.

Reporting a vulnerability

Please report vulnerabilities privately, through GitHub security advisories, not in a public issue. See SECURITY.md.

Privacy and security

The security model of the desktop app, and what KubeStacks connects to.

Helm values

Every setting the chart has.