Skip to content
Beta

Kubernetes cluster access

Access to a cluster is given per person and per cluster. Each person holds a role on a cluster, or none, and everything they do inside it carries that role: their kubeconfig, the console's dashboard, growing a volume. There is no shared admin kubeconfig to pass around.

Roles

RoleIn the cluster
AdminFull administration, roles and namespaces included (cluster-admin)
EditorCreate and change workloads, Services, routes, claims and Secrets in every namespace except the system ones (edit). Can list namespaces, storage classes, ingress classes and gateway classes; cannot see nodes, manage roles or create namespaces
ViewerRead what runs in every namespace, except Secrets (view); change nothing

The system namespaces are kube-system, kube-public, kube-node-lease and the two the managed gateway runs in. Editors have no role in them, so they can neither read their Secrets nor change what runs there. What they can run in the other namespaces is set by pod security.

Inside the cluster, each role is a Kubernetes group: sahabti:cluster-admins for admins, sahabti:developers for editors and sahabti:viewers for viewers. Your credentials carry the group of your role and name you by your email address, as how the cluster knows you explains. A cluster admin can bind these groups in their own roles, for example to let viewers read a custom resource.

Pod security

Every namespace except the system ones follows the Kubernetes Pod Security Standards:

StandardWhat happens
baseline, enforcedA pod that would weaken its worker's isolation is refused: privileged containers, the host's network, process or IPC namespaces, host paths, host ports and capabilities beyond the default set.
restricted, warned and auditedA pod that is not also hardened (running as non-root, no privilege escalation, a seccomp profile, every capability dropped) still runs, and kubectl prints a warning naming what to change.

So what an editor deploys cannot take over a worker or reach the cluster's own components on it.

A cluster admin can relax or tighten one namespace with the standard labels, which override the defaults for that namespace only:

bash
# privileged pods allowed, for example a node exporter, and no warnings about them
kubectl label namespace monitoring pod-security.kubernetes.io/enforce=privileged pod-security.kubernetes.io/warn=privileged
# hardened pods only
kubectl label namespace payments pod-security.kubernetes.io/enforce=restricted

Editors cannot change namespace labels, so they cannot lift the standard they work under. A relaxed namespace lets everyone who can create pods in it, editors included, run privileged pods there: keep such namespaces for the workloads that need them.

Turn it on for an older cluster

A cluster created before these defaults existed runs without them until you turn them on: a namespace without labels admits privileged pods there, and editors can run them on the workers. The cluster's Settings say so under Pod Security; turn it on there, or send podSecurity: true to PATCH /v1/kubernetes/clusters/{id}/settings, and the cluster gets exactly the defaults above.

  • Pods that run already keep running. A pod that breaks baseline is refused the next time it is created, for example when its Deployment rolls out or its worker is replaced, so check your workloads first and label the namespaces that need more before you turn it on.
  • The control plane restarts into it one node at a time, and the cluster shows Updating until it is done. Without high availability, the cluster's API is unavailable for about a minute; your workloads keep running.
  • If the API server does not come back with it, that node goes back to how it was, the setting reads off again, and the cluster shows Degraded with the reason. Your workloads are not changed.
  • Once on, it stays on. To let one namespace run privileged pods, label it as shown above.

Who holds a role

  • Workspace owners are admins of every cluster in the workspace. Their access cannot be changed or revoked.
  • Whoever creates a cluster becomes its admin.
  • Everyone else holds the role they were given, and no role until then, whatever their role in the workspace. Changing someone's workspace role leaves their cluster roles as they are; change or revoke those on each cluster.

When access became per cluster, every existing cluster kept the people who could reach it: workspace owners and admins became its admins and developers its editors.

Give, change and revoke access

Open the cluster, go to Access and find People with access: everyone with a role, who gave it and when.

  • Grant access gives a member of the workspace a role. Invite someone to the workspace first if they are not a member yet.
  • A person's menu changes their role or revokes their access.

Workspace owners and admins manage the access of every cluster in the workspace; a cluster's admins manage that cluster's. Nobody can give a role above their own, and a cluster always keeps an admin. Every change is recorded with who made it.

Who can reach the API

The API access card in the cluster's Access section decides who can reach the cluster's Kubernetes API over the network. Your credentials still decide what a request may do; this setting decides where a request may come from.

SettingWho can reach the API
Public, open to the internetAny address. Every request still needs a valid kubeconfig.
Public, only these networksOnly the IPv4 addresses and networks you list, the authorized networks. Everything else gets no answer.
PrivateNobody on the internet. The cluster is reached from inside your workspace network, at its private endpoint.

Clusters created before this setting existed are public and open to the internet, and stay that way until you change them. The card warns about an open endpoint: if you know where you connect from, limit it to those networks.

Workspace owners and admins, and the cluster's admins, can change the setting. Everyone else can see it. A change takes effect within a few seconds, and connections already open from an address the new setting leaves out are cut.

Authorized networks

  • List up to 20 IPv4 addresses or networks in CIDR form, one per line, such as 203.0.113.7 or 198.51.100.0/24. A single address is saved as /32, and a network is saved by its first address, so 198.51.100.9/24 becomes 198.51.100.0/24.
  • 0.0.0.0/0 is not accepted: to admit every address, choose open to the internet instead.
  • Add my IP adds the address you are connecting from. If the card tells you that address is IPv6, add the IPv4 address your network uses instead: the API endpoint is IPv4 only.
  • Before you save, the card warns you if the list leaves out the address you are using, so you do not lock yourself out by accident.

Private access from your workspace network

A cluster has two endpoints, and the card shows both:

  • Public endpoint: https://<address>:<port> on the internet, reachable as the setting says.
  • Private endpoint: https://<address>:6443 inside your workspace network, reachable from any instance, virtual machine or pod in that network, whatever the setting.

When a cluster is private, kubeconfigs downloaded from then on point at the private endpoint. Download a new kubeconfig and use it from a machine inside the workspace network, for example a virtual machine; a kubeconfig downloaded earlier still names the public endpoint and stops working. After you switch back to public, download a new kubeconfig to connect from outside: one downloaded while the cluster was private only works inside the workspace network.

Platform access

The platform's own connections to your cluster, such as the dashboard in the console, are always allowed, whatever the setting. They never appear in your list, and they still need credentials like any other request.

Two kinds of kubeconfig

Both come from the Connect card in the cluster's Access section, and both carry your own role.

Download kubeconfig gives you a file that keeps itself working. Instead of a long-lived certificate, it holds a token that can do exactly one thing: ask for a fresh one-hour credential for this cluster. kubectl does that by itself, using sh and curl, so it runs on macOS, Linux and WSL. It keeps the credential in ~/.kube/cache/sahabti/, readable by you alone, and asks for a new one five minutes before it expires, so your commands do not wait on the platform. The token lasts a year and is listed on your workspace's API tokens page, where you can revoke it.

12-hour kubeconfig gives you a plain file with a certificate that expires after twelve hours. It needs nothing but kubectl, which makes it the one for Windows without WSL or a quick session on a borrowed machine. Download a new one when it expires.

Keep kubeconfigs private: anyone holding one acts as you in that cluster.

How the cluster knows you

The cluster knows you by your email address, in lowercase, and knows your role by its group. kubectl auth whoami shows both:

text
ATTRIBUTE   VALUE
Username    [email protected]
Groups      [sahabti:viewers system:authenticated]

A refusal names you the same way. Dana is a viewer, so creating a pod is refused:

text
Error from server (Forbidden): pods is forbidden: User "[email protected]" cannot create resource "pods" in API group "" in the namespace "default"

A kubeconfig names its entries after you and the cluster, never after your role:

EntryNameExample
Clustersahabti-<cluster>sahabti-smoke-1
User<email>@sahabti-<cluster>[email protected]@sahabti-smoke-1
Contextthe same as the user, already selected[email protected]@sahabti-smoke-1

Since every name includes the cluster, you can keep the kubeconfigs of several clusters together, for example export KUBECONFIG=smoke-1.kubeconfig:prod.kubeconfig, and switch between them with kubectl config use-context.

Roles come only from the groups. In your own role bindings, name the groups, not an email address: a binding that names an address stays with that address when its owner changes it.

When you change your email address, the cluster sees the new one from the next credential issued to you: at the dashboard's next refresh, within the hour through a self-renewing kubeconfig, and through a 12-hour kubeconfig only once you download a new one. The entry names inside a kubeconfig stay as they were downloaded; download a new one to rename them.

A kubeconfig downloaded before these names keeps working as it is. Its entries are sahabti-<cluster> and sahabti-<cluster>-admin whatever your role: that -admin never meant the admin role. Clusters also used to know you by an internal ID, sahabti:user: followed by letters and digits, rather than by your email. A role bound to such a name no longer applies: bind it to a group instead.

When a change applies, and when access ends

Your role and email address are read again every time a credential is issued:

  • The dashboard follows a change at its next refresh.
  • A self-renewing kubeconfig keeps each credential for up to 55 minutes, so a change or a revoke applies within the hour. After your own role changes, delete ~/.kube/cache/sahabti/ to use the new one at once. A self-renewing kubeconfig downloaded before this cache existed asks for a credential at every command; download a new one to keep it between commands.
  • A 12-hour kubeconfig keeps the role it was issued with until it expires. It cannot be revoked early, which is why it is short.

Access also ends when:

  • You leave the workspace: every role you held goes with your membership, and joining again starts with none.
  • You revoke the kubeconfig's token on the API tokens page: it stops at its next renewal.
  • The cluster is deleted: every self-renewing kubeconfig for it stops at once.

For automation

For a pipeline that deploys into the cluster, create a Kubernetes service account with a role that covers what it deploys, and give the pipeline that account's token, rather than a person's kubeconfig.

To manage clusters themselves — create, scale, delete, list volumes, see and change who has access — from scripts or an AI agent, use the API or MCP: list_kubernetes_clusters, get_kubernetes_cluster, create_kubernetes_cluster, scale_kubernetes_cluster, delete_kubernetes_cluster, list_kubernetes_cluster_volumes, list_kubernetes_volumes, delete_kubernetes_volume, list_kubernetes_access, set_kubernetes_access and revoke_kubernetes_access. Changing access acts as a person, so it works with a person's sign-in but not with an API token. Neither ever hands out a kubeconfig.

Who can reach a cluster's API is GET and PUT /v1/kubernetes/clusters/{id}/api-access, or get_kubernetes_api_access and set_kubernetes_api_access over MCP. Send one of:

json
{ "mode": "public", "openToInternet": true }
{ "mode": "public", "authorizedNetworks": ["203.0.113.0/24", "198.51.100.7"] }
{ "mode": "private" }

create_kubernetes_cluster and POST /v1/kubernetes/clusters take the same object as apiAccess; without it a new cluster is open to the internet. Changing the setting needs a workspace owner or admin, or one of the cluster's admins, signed in, so API tokens can read it but not change it.

How the API endpoint is protected

The cluster's API endpoint answers only the addresses its API access setting admits. To those, it answers health checks to anyone and every other request only to a valid credential. Secrets are encrypted at rest, the control plane runs none of your workloads, pods follow the pod security standards, and each cluster has its own certificate authority.