Access, auth & credentials
Reach private clusters over Tailscale, sign in to EKS with IAM and no exec plugin, and reuse one secret across connections from a central credentials manager.
Kubo is a client, not a service. There is no backend of ours between your phone and your cluster: every request goes straight from the app to the endpoint you configured, over whatever network already reaches it.
Reaching a private cluster
Most clusters worth managing are not on the public internet. Kubo supports two paths:
Tailscale operator API-server proxy. The Tailscale Kubernetes operator’s API-server proxy lets the app reach a private cluster over your tailnet and authenticate by tailnet identity — which means the app stores no cluster credentials at all. Access is granted by a tailnet ACL grant mapping you to a Kubernetes group, plus RBAC on that group. The Add-cluster screen links to a least-privilege setup guide for exactly this arrangement.
Direct. A bearer token or a client certificate against the API server URL, with a custom CA where you use one.
EKS without an exec plugin
A kubeconfig for EKS or GKE usually authenticates by shelling out to a CLI
(aws eks get-token). A phone cannot shell out. Rather than making those clusters
un-addable, Kubo builds the sign-in token itself: a hand-rolled SigV4 presign of the
STS call, exactly equivalent to what the CLI produces, cached and refreshed per request.
Static keys, temporary STS credentials and assume-role are all supported, and an
eks:DescribeCluster call can auto-fill the endpoint and CA for you.
Minting the token needs no IAM permission of its own — what an identity may do inside
the cluster is decided separately by Kubernetes RBAC, as it should be. The only AWS call the
app makes at all is the optional eks:DescribeCluster behind the “fetch endpoint & CA”
button, and a least-privilege policy for it is linked from the Add-cluster screen.
Kubeconfig contexts that do use an exec plugin are imported with blank credentials and a note, so you can edit the cluster and add a token rather than being told “unsupported”.
Where secrets live
Tokens, passwords, API keys and PEM material live only in the platform’s secure storage (Keychain / Keystore and their desktop equivalents). Connection metadata — URLs, names, which credential a connection uses — is ordinary non-secret JSON that references the secret by id.
The credentials manager
One secret is often used by more than one connection: an AWS key pair backs both an S3 endpoint and an EKS cluster; an internal CA is shared by half your services; a bearer token is accepted by Prometheus, Traefik and kube-state-metrics alike.
So credentials are their own object. A credential is a named bundle of one kind — AWS keys, bearer token, Basic auth, API key, client certificate or CA bundle — and a connection stores only its id. Two credentials are interchangeable for a slot exactly when they share a kind.
Every add or edit form uses the same control: pick an existing compatible credential, or create one inline. A management screen (Settings → Connections → Credentials) lists, edits and removes them grouped by kind. Connections saved before the manager existed keep working through a legacy fallback, and are migrated the next time you edit them.
Everywhere the app asks for a secret it is password-manager aware: fields are wrapped in an autofill group with the right hints, so the OS wallet offers to fill them and offers to save them afterwards.
What the app will not do
- No YAML editing. Manifests are read-only. Editing a manifest on a phone is how outages happen.
- No
apply,editorport-forwardin the kubectl console — the verbs that need a shell or a file are not in the grammar. - Destructive actions confirm. Deletes, purges, force-closes and rollbacks all go through a confirm dialog.
- Optional permissions degrade quietly. Metrics, events and CoreDNS discovery are all detection-gated: a Forbidden means “this feature is off”, not an error screen.