Skip to content

Choose an RBAC posture

Two independent decisions control what the agent can do in your cluster:

  1. Scope — cluster-wide, or a Role in each of a named set of namespaces.
  2. Posture — how much the agent may change within that scope.

Both are enforced by Kubernetes itself, not by Seylo. That is the point: the tier model in the portal can be argued with in a code review; an RBAC grant cannot be argued with at all.

Pick a named posture rather than assembling individual toggles. The most common RBAC mistake here is a half-set combination nobody meant — browse enabled with writes left on, say.

Posture The agent can Use when
read-only See the cluster and change nothing in it You want visibility first, or a cluster Seylo should never mutate
deploy Read everything it needs, and create/update/patch the workload kinds a release touches. No delete anywhere Most clusters. This is the product’s intended posture
admin deploy, plus the destructive tier: delete and evict pods, cordon and drain nodes, delete workloads Someone is expected to remediate from the portal
(unset) Whatever the individual toggles say An existing install keeps exactly the Role it has

read-only grants exactly one write, and it is not a cluster permission

Section titled “read-only grants exactly one write, and it is not a cluster permission”

get/patch/update on the agent’s own credential Secret, narrowed by name to seylo-agent-credential.

The agent has to persist its own rotated credential or it cannot stay connected. This is stated here rather than left to be discovered in a rendered Role.

An agent that can edit Roles can widen its own permissions. That is a decision no preset should make on your behalf, so it is never included in a posture — admin included. If you need it, you turn it on deliberately, and you should read the warning below first.

  • pods/exec and pods/attach appear in no grant this chart can produce. Container exec is not implemented and will not be.
  • Reading Secret values. There is no broad secrets read rule in the base grant, and Seylo’s refusal to return Secret values is enforced in code — in the agent before serialisation, and again on the server. See how secrets are handled.

Both are off by default.

Destructive (tier 3). Permits deleting PersistentVolumeClaims — which deletes the real disk when the bound volume’s reclaim policy is Delete — PersistentVolumes, StorageClasses, Namespaces (cascading to everything inside), CustomResourceDefinitions (deleting every custom resource of that type) and VolumeSnapshots.

The portal additionally requires the object’s exact name to be typed and the consequences acknowledged, and shows the reclaim policy, the cascade contents and the custom-resource count first. Those are guardrails on someone who already holds the permission. Leaving it off is the control that does not depend on anybody reading a dialog.

RBAC (tier 4). With it the agent can write Roles, RoleBindings, ClusterRoles and ClusterRoleBindings — including ones that widen its own permissions.

Cluster-wide Namespace-scoped
Binding One ClusterRole + ClusterRoleBinding One Role + RoleBinding per managed namespace
Blast radius Every namespace in the cluster Exactly the listed namespaces, enforced by Kubernetes
Namespace discovery The agent lists namespaces itself ImpossiblewatchNamespaces is required
Create namespace / namespace wizard Works Does not work
Auditing it yourself Read the single ClusterRole kubectl get rolebinding -A | grep agent lists the complete reachable set
Choose it when You own the cluster and want Seylo to onboard namespaces Someone else owns the cluster and wants a hard, provable boundary

Seylo additionally enforces the scope itself: a command naming a namespace outside the watched list is refused before any API call. So even a compromised Seylo server cannot widen the blast radius beyond what you configured — defence in depth on top of Kubernetes RBAC.

The one real consequence of namespace scoping

Section titled “The one real consequence of namespace scoping”

A namespace-scoped install cannot read Nodes, so the default kubelet metrics source collects nothing for that cluster.

Node is a cluster-scoped object. A Role cannot grant nodes, nodes/proxy or nodes/metrics at all — not as a configuration choice, but because Kubernetes RBAC does not permit a namespaced Role to reference a cluster-scoped resource. No amount of editing the manifest changes this.

Still works, in full: inventory, the dashboard matrix, drift and environment comparison, history, releases, image patches, rollout restarts, manifest edits, ConfigMap and env edits, rollout status and follow-through, dry-run validation, approvals, audit, scheduled deployments, and pod-failure alerts (those come from events and pod status, both namespaced).

Does not work: node-proxy metrics — so no CPU, memory, network I/O or CPU throttling figures, and therefore no history and no right-sizing recommendations. These are reported as unknown, never as zero; the Insights page names the reason rather than drawing an empty chart.

Also unavailable: creating and listing namespaces, and the namespace wizard.

What to do instead, in order of preference

Section titled “What to do instead, in order of preference”
  1. Set the cluster’s metrics source to prometheus and give the agent an in-cluster Prometheus URL. Best coverage — CPU, memory, network and throttling with history — and it needs no cluster-scoped RBAC. The agent scrapes it from inside your cluster; Seylo never connects to it.
  2. Set the source to metrics-server. Works with namespaced RBAC for pod metrics, so CPU and memory work. There is no network I/O or throttling from this source for anyone, namespaced or not.
  3. Grant the cluster-scoped variant, if the cluster owner is willing. This is the only way to get the kubelet source, and it is also what the namespace wizard needs.
  4. Accept metrics-free management. Everything in the “still works” list is unaffected. This is a perfectly reasonable posture for a cluster whose owner wants a provable, namespace-shaped boundary.

The chart prints all of this in its helm install output when you choose namespace scoping.

The base grant covers only what releases, environment edits, restarts and metrics need. Browsing arbitrary kinds — StatefulSets, DaemonSets, CronJobs, Jobs, PVCs and any CRD — needs broad read, so it is a deliberate opt-in, off by default. With it off, the Resources page says exactly which permission is missing rather than showing an empty list.

Kubernetes RBAC has no deny rule and cannot express “everything except secrets”, so there are only two honest choices:

Mode What it grants Trade-off
wildcard (default) get/list/watch on everything, including CRDs installed later The ServiceAccount can read Secrets at the API level. Seylo’s refusal to expose values is enforced in code, not by RBAC. Anyone able to replace the agent’s image could read every Secret in the cluster with this token
enumerated The core group without secrets, plus the API groups you list RBAC itself makes Secret reads impossible. Cost: a CRD group must be listed before it can be browsed

Both modes are read-only. No write verb is ever granted by this block.

A write the agent cannot perform is not refused opaquely. The error names the missing verb, the resource, and the exact setting that turns it on. Seylo also reads the agent’s real grant back and shows it in the portal, so you can see what the agent may do before something is refused rather than after.