Narrow Secret RBAC: per-namespace Roles and a restricted manager cache #8

Open
opened 2026-10-09 12:43:03 +00:00 by niklas · 0 comments
Owner

Decision (2026-10): stay cluster-wide for now; this tracks the follow-up.

Today

The chart default is a ClusterRole with full verbs on Secrets in every namespace, and the manager cache is unrestricted, so the first Get on a Secret starts a cluster-wide Secret informer (list/watch everywhere). Anyone who compromises the operator pod or image can read every Secret in the cluster. rbac.namespaced: true only gives a Role in the release namespace, which cannot serve tenant namespaces (alert-source webhook Secrets). DESIGN.md §9 documents this.

Where Secrets are touched after the redesign

  • <TerdutServer>-operator-key: in the TerdutServer's namespace (create/get/delete).
  • <TerdutAlertSource>-terdut-webhook: in the alert source's namespace (create/get/delete, Owns).
  • Zalando credentials Secret: TerdutServer's namespace (get).

Proposal

  • Chart value watchNamespaces: []; render a Role + RoleBinding per listed namespace for Secrets/Deployments/Services/PDBs.
  • Restrict the manager cache (cache.ByObject for those types) to them; keep CRDs/events/namespaces cluster-wide (namespaces get only, for allowedTeams selectors).
  • A CR in an unlisted namespace gets a clear NamespaceNotEnabled condition rather than a cache error.
  • Optionally watchNamespaces: [] meaning all namespaces with a ClusterRole, as an explicit single-tenant opt-in.
  • Drop the misleading rbac.namespaced toggle.
  • Onboarding a tenant namespace then becomes a values change, which makes allowedTeams enforceable by the cluster.
Decision (2026-10): stay cluster-wide for now; this tracks the follow-up. ## Today The chart default is a `ClusterRole` with full verbs on `Secrets` in every namespace, and the manager cache is unrestricted, so the first `Get` on a Secret starts a cluster-wide Secret informer (list/watch everywhere). Anyone who compromises the operator pod or image can read every Secret in the cluster. `rbac.namespaced: true` only gives a Role in the release namespace, which cannot serve tenant namespaces (alert-source webhook Secrets). DESIGN.md §9 documents this. ## Where Secrets are touched after the redesign - `<TerdutServer>-operator-key`: in the TerdutServer's namespace (create/get/delete). - `<TerdutAlertSource>-terdut-webhook`: in the alert source's namespace (create/get/delete, `Owns`). - Zalando credentials Secret: TerdutServer's namespace (get). ## Proposal - Chart value `watchNamespaces: []`; render a Role + RoleBinding per listed namespace for Secrets/Deployments/Services/PDBs. - Restrict the manager cache (`cache.ByObject` for those types) to them; keep CRDs/events/namespaces cluster-wide (namespaces `get` only, for `allowedTeams` selectors). - A CR in an unlisted namespace gets a clear `NamespaceNotEnabled` condition rather than a cache error. - Optionally `watchNamespaces: []` meaning all namespaces with a ClusterRole, as an explicit single-tenant opt-in. - Drop the misleading `rbac.namespaced` toggle. - Onboarding a tenant namespace then becomes a values change, which makes `allowedTeams` enforceable by the cluster.
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: niklas/terdut-operator#8