Kubernetes RBAC: Toegangscontrole Zonder Gedoe

ServiceAccounts, Roles en RoleBindings in Kubernetes — hoe het werkt, waar het misgaat en praktische voorbeelden om RBAC snel en veilig op te zetten.

Jean-Pierre Broeders

Freelance DevOps Engineer

27 maart 20265 min. leestijd
Kubernetes RBAC: Toegangscontrole Zonder Gedoe

Kubernetes RBAC: Toegangscontrole Zonder Gedoe

Standaard draait alles in Kubernetes onder het default ServiceAccount. Dat klinkt onschuldig, maar het is alsof iedereen op kantoor dezelfde sleutel heeft. Vroeg of laat gaat er iemand een deur open die dicht had moeten blijven.

RBAC — Role-Based Access Control — is de manier om dat te fixen. Niet sexy, wel noodzakelijk. En als het eenmaal staat, hoeft er eigenlijk nooit meer naar omgekeken te worden.

Waarom RBAC Ertoe Doet

Een veelgemaakte fout: een CI/CD pipeline die met cluster-admin rechten draait. Werkt prima, totdat iemand per ongeluk een kubectl delete namespace production uitvoert. Of totdat een gecompromitteerde pod volledige API-toegang heeft.

RBAC voorkomt dat soort rampen. Het principe is simpel: geef elke workload en elke gebruiker precies de rechten die nodig zijn. Niet meer.

De Bouwstenen

Vier resources vormen de kern:

ResourceScopeWat het doet
RoleNamespaceDefinieert permissies binnen één namespace
ClusterRoleCluster-breedDefinieert permissies voor het hele cluster
RoleBindingNamespaceKoppelt een Role aan een gebruiker of ServiceAccount
ClusterRoleBindingCluster-breedKoppelt een ClusterRole aan een gebruiker of ServiceAccount

Het verschil tussen Role en ClusterRole is puur scope. Een Role geldt voor één namespace, een ClusterRole voor alles. Dat klinkt triviaal, maar het vergeten van dit onderscheid is verantwoordelijk voor een hoop te brede rechten in productie.

Een Praktijkvoorbeeld

Stel: er draait een monitoring-agent die pods mag lezen maar niks mag wijzigen. De setup ziet er zo uit:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: monitoring-agent
  namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: monitoring-pod-reader
subjects:
  - kind: ServiceAccount
    name: monitoring-agent
    namespace: monitoring
roleRef:
  kind: ClusterRole
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

Drie manifests, klaar. De monitoring-agent kan nu pods lezen in alle namespaces, maar verder niks. Geen secrets inzien, geen deployments aanpassen, geen nodes draineren.

ServiceAccounts: Het Vergeten Puzzelstukje

Elke pod draait onder een ServiceAccount. Zonder expliciete toewijzing wordt het default account van die namespace gebruikt. Dat account heeft standaard nauwelijks rechten, maar het punt is: alle pods delen het. Eén pod compromised betekent dat een aanvaller dezelfde rechten heeft als alle andere pods in die namespace.

De oplossing is simpel: maak een dedicated ServiceAccount per applicatie.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: payment-service
  namespace: production
automountServiceAccountToken: false

Die laatste regel — automountServiceAccountToken: false — is belangrijk. Standaard mount Kubernetes een API-token in elke pod. Als de applicatie de Kubernetes API niet nodig heeft (en dat geldt voor de meeste), zet dit dan uit. Minder aanvalsvlak.

Veelgemaakte Fouten

Te brede wildcards. Het is verleidelijk om resources: ["*"] en verbs: ["*"] te gebruiken. Werkt altijd, maar geeft effectief cluster-admin rechten. Nooit doen in productie.

ClusterRoleBinding waar RoleBinding volstaat. Als een service alleen in z'n eigen namespace hoeft te werken, gebruik dan een RoleBinding. Geen reden om cluster-brede rechten te geven.

Vergeten om RBAC te testen. Na het aanmaken van roles kan getest worden of het klopt:

kubectl auth can-i list pods \
  --as=system:serviceaccount:monitoring:monitoring-agent
# yes

kubectl auth can-i delete deployments \
  --as=system:serviceaccount:monitoring:monitoring-agent
# no

Die can-i check is goud waard. Draai het na elke RBAC-wijziging.

Aggregated ClusterRoles

Een handige feature die weinig teams gebruiken: aggregation. Hiermee worden ClusterRoles automatisch samengevoegd op basis van labels.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-extras
  labels:
    rbac.example.com/aggregate-to-monitoring: "true"
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: monitoring-aggregate
aggregationRule:
  clusterRoleSelectors:
    - matchLabels:
        rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # wordt automatisch gevuld

Handig als meerdere teams onafhankelijk rechten willen toevoegen aan dezelfde rol. Het voorkomt merge-conflicten in Git en maakt RBAC modulair.

Pod Security Standards

RBAC regelt wie wat mag doen via de API. Maar wat een pod zelf mag op OS-niveau — root draaien, host-networking, privileged containers — dat valt onder Pod Security Standards (PSS).

Sinds Kubernetes 1.25 is dit ingebouwd via de Pod Security Admission controller. Drie levels:

LevelBeschrijving
privilegedGeen restricties (alleen voor system-level workloads)
baselineBlokkeert de ergste dingen (hostNetwork, privileged containers)
restrictedBest practice — geen root, geen capabilities, read-only rootfs

Toewijzen aan een namespace gaat via labels:

apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/warn: restricted

De warn mode is handig om eerst te testen zonder dingen te breken.

Praktische Checklist

Een snelle checklist voor RBAC in productie:

  • Elk team of service heeft een eigen ServiceAccount
  • automountServiceAccountToken: false tenzij echt nodig
  • Roles in plaats van ClusterRoles waar mogelijk
  • Geen wildcards in rules
  • kubectl auth can-i checks in CI/CD pipeline
  • Pod Security Standards op restricted voor productie-namespaces
  • RBAC manifests in version control, niet handmatig aangemaakt

Niets spectaculairs. Gewoon solide basis-hygiëne die voorkomt dat een kleine fout een grote ramp wordt. De meeste security-incidenten in Kubernetes-omgevingen komen niet door geavanceerde aanvallen, maar door te brede rechten die niemand ooit heeft ingeperkt.

Wil je op de hoogte blijven?

Schrijf je in voor mijn nieuwsbrief of neem contact op voor freelance projecten.

Neem Contact Op