Choose an RBAC posture
Two independent decisions control what the agent can do in your cluster:
- Scope — cluster-wide, or a
Rolein each of a named set of namespaces. - 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.
Posture
Section titled “Posture”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.
No posture ever grants RBAC write
Section titled “No posture ever grants RBAC write”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.
What is never granted, at any setting
Section titled “What is never granted, at any setting”pods/execandpods/attachappear in no grant this chart can produce. Container exec is not implemented and will not be.- Reading Secret values. There is no broad
secretsread 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.
The two grants to think hardest about
Section titled “The two grants to think hardest about”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 vs namespace-scoped
Section titled “Cluster-wide vs namespace-scoped”| 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 | Impossible — watchNamespaces 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”- Set the cluster’s metrics source to
prometheusand 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. - 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. - Grant the cluster-scoped variant, if the cluster owner is willing. This
is the only way to get the
kubeletsource, and it is also what the namespace wizard needs. - 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.
Browsing arbitrary resource kinds
Section titled “Browsing arbitrary resource kinds”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.
When a permission is missing
Section titled “When a permission is missing”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.