Where in-cluster deployment fits, and where it does not
Headlamp in-cluster deployment suits a setup where the browser UI needs close access to one cluster and the access pattern is already meant to live inside Kubernetes. It is a poor fit if the aim is to avoid deploying anything into the cluster at all, or if local kubeconfig access already gives enough reach from a desktop application.
The desktop application path is the cleaner option for a lot of day-to-day admin work. It connects with existing kubeconfig files and does not need a service account or a pod sitting inside the cluster. That keeps the access plane outside the target environment, which is usually where awkward surprises stay smaller.
In-cluster deployment makes more sense when the UI must sit alongside the workloads it manages, or when the operator wants the same Kubernetes RBAC model applied to the interface itself. It also suits multi-cluster management better when different clusters need the same web-based entry point and the access model is already standardised. The trade-off is simple enough: the UI becomes part of the cluster security story, not a separate tool with cleaner edges.
Service accounts, namespace scope, and the permissions Headlamp actually needs
Headlamp does not need blanket access just because it is a management UI. A service account tied to a narrow namespace role is enough for many setups, especially where the UI only needs to read a slice of the cluster or manage one application area. Giving it cluster-wide rights because it is convenient is how a browser tab turns into an incident.
Namespace scope works well when access is tied to a team space, an application namespace, or a Project-style view built from namespaces and labels. In that shape, the role can stay focused on the objects that matter there: pods, deployments, services, config maps, secrets where appropriate, and the ability to inspect live state. If the UI is used only for browsing and light operations, there is no sensible reason for it to see the whole cluster.
Bind the UI to the narrowest workable RBAC role
Start with read access and only add verbs that the actual workflow needs. If the use case is inspection, logs, and basic resource viewing, then write permissions are just risk with a nicer interface. If scaling or deletion is part of the job, grant those verbs only in the namespaces that need them.
A Headlamp instance bound to a service account should not inherit rights just because the person behind the keyboard is trusted. The service account is the boundary, not the human mood on a Friday afternoon. Separate the UI account from personal admin accounts and from automation accounts that do different jobs.
If the deployment supports Projects or namespace-scoped views, treat them as a control, not a convenience feature. They help keep the interface pointed at a limited resource set, but they do not replace RBAC. Labels and namespace grouping are only useful if the role backing them is just as narrow.
Keep cluster-wide reads separate from write paths
Cluster-wide read access is often reasonable for inventory, discovery, and debugging. It is a different matter from allowing writes across the whole cluster through the same identity. Mixing the two gives the UI more reach than most operators actually need.
Keep cluster-wide reads on one role and writes on another, then bind them only where the workflow justifies it. A common mistake is to grant broad read access, then quietly add write verbs because one screen in the UI needs them. That is how permission creep starts, and Kubernetes RBAC does not care that it was only meant to be temporary.
For mixed environments, split responsibilities by cluster and by namespace. Development can tolerate broader access than production, but the permissions should still follow the same shape. A single service account with broad rights across every environment saves time at the start and creates a neat little pile of regret later.
Hard edges to test before you trust the setup
Test the actual actions, not just the login. Browsing resources, opening manifests, scaling a workload, deleting an object, and reading logs all use different permissions in practice. If one of those succeeds where it should not, the boundary is already gone.
Check what happens when the service account has no rights in a neighbouring namespace. A UI that happily renders cross-namespace data without the right RBAC checks is not behaving safely, even if the main dashboard looks fine. Also check what the desktop application can reach through kubeconfig, since that path may carry more access than the in-cluster variant if the file is broad.
Multi-cluster management needs the same discipline. A cluster list in the UI is harmless until one context carries more privilege than the others and the operator stops noticing which target is live. That sort of mistake usually starts with “just for testing” and ends with a cleanup ticket nobody enjoys.
The last check is mundane but worth doing: verify that the in-cluster deployment cannot do anything useful if the service account token is stolen. If that answer is “too much”, the RBAC role is still too broad.

