CoursesFluxAdvanced

Multi-tenancy & RBAC

Isolate teams safely.

Advanced14 min · lesson 9 of 12

Flux does multi-tenancy through Kubernetes primitives rather than a bespoke project model. The pattern: each tenant gets a namespace, a ServiceAccount with scoped RBAC, and their own Kustomizations/sources — and Flux impersonates that ServiceAccount when reconciling the tenant’s resources (serviceAccountName on the Kustomization). So a tenant’s GitOps can only do what their ServiceAccount is allowed to do, enforced by the same RBAC that governs everything else in the cluster.

tenant kustomization
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata: { name: team-a-apps, namespace: team-a }
spec:
serviceAccountName: team-a # Flux impersonates this SA...
sourceRef: { kind: GitRepository, name: team-a-repo, namespace: team-a }
path: ./apps
prune: true
# ...so team-a can only create what team-a’s RBAC permits — no cross-tenant reach

Isolation by impersonation

This impersonation model is elegant: there is no separate Flux permission system to keep in sync with Kubernetes RBAC — the cluster’s RBAC is the boundary. A platform team owns the cluster-wide Flux and the tenant scaffolding; each tenant reconciles within their namespace under their own SA, unable to touch other tenants or cluster-scoped resources unless granted. Combined with source restrictions (a tenant can only use their own repos), this keeps many teams safely on one Flux.

Without impersonation, a tenant reconciles as cluster-admin
By default the kustomize-controller runs with broad permissions, so a Kustomization without serviceAccountName applies resources with the controller’s own (powerful) rights — meaning a tenant’s manifests could create anything. For multi-tenant clusters, always set serviceAccountName and scope each tenant’s RBAC, and consider enforcing it (a policy that rejects Kustomizations lacking a tenant SA). Impersonation is the boundary; skipping it removes the isolation entirely.