RBAC no Kubernetes: como controlar acesso no cluster

Numa fintech que passa por auditoria PCI, uma das primeiras perguntas que o auditor faz é: “quem consegue fazer o quê dentro do cluster?”. Se a resposta começa com “então…”, já começou mal. Quando vivi essa conversa pela primeira vez, o ambiente tinha 15 pessoas com acesso admin no Kubernetes. Fechamos em zero fora dos times de SRE e Cyber, e ninguém do desenvolvimento acessando o cluster diretamente: deploy e visibilidade passando por GitOps (ArgoCD). O que tornou essa mudança possível (e auditável) foi o RBAC.

RBAC (Role-Based Access Control) é o mecanismo nativo do Kubernetes para autorizar quem pode fazer o quê em quais recursos. Ele funciona com quatro objetos: Role e ClusterRole definem permissões (verbos sobre recursos), enquanto RoleBinding e ClusterRoleBinding conectam essas permissões a usuários, grupos ou ServiceAccounts. Role e RoleBinding valem dentro de um namespace; as versões Cluster valem para o cluster inteiro.

Os 4 objetos do RBAC na prática

A menor unidade útil: uma Role que permite ler pods num namespace, e um RoleBinding que entrega isso a um grupo.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: pagamentos
  name: leitor-pods
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: pagamentos
  name: devs-leitura
subjects:
- kind: Group
  name: time-pagamentos
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: leitor-pods
  apiGroup: rbac.authorization.k8s.io

A regra de leitura que eu uso para não me perder: Role é o cargo, RoleBinding é a contratação. Escrever o cargo não dá poder a ninguém; o poder nasce no binding. E o detalhe que derruba gente na prova CKA e em produção: RoleBinding pode referenciar uma ClusterRole para conceder aquilo só dentro de um namespace. É assim que você reaproveita uma ClusterRole “view” em vinte namespaces sem duplicar YAML.

Como eu modelo isso em produção: namespace por microserviço

Nos ambientes EKS que operei, cada microserviço tem seu namespace (dezenas por cluster). Isso faz o RBAC praticamente se desenhar sozinho:

  1. Pessoas não recebem acesso direto ao cluster. Deploy é via ArgoCD, e é lá que o time acompanha sync, histórico e diff. O acesso humano de exceção é somente leitura, e restrito.
  2. ServiceAccounts de aplicação nascem sem nada. Se o pod não fala com a API do Kubernetes (a maioria não fala), a ServiceAccount dele não ganha binding nenhum, e eu ainda desligo o token com automountServiceAccountToken: false.
  3. Quem precisa de poder de verdade (SRE/Cyber) entra por grupo, mapeado a partir do IAM, nunca por usuário individual solto no YAML.

Essa arquitetura tem um efeito colateral bom para auditoria: os logs de audit do control plane vão para um SIEM central, fora do cluster, e como cada ação carrega o namespace e a identidade, responder “quem mexeu no Secret do serviço X” vira uma query, não uma investigação. Se você ainda guarda Secrets e ConfigMaps sem pensar em quem pode lê-los, RBAC é a outra metade desse assunto.

RBAC no EKS: o mapeamento IAM que ninguém te conta

No EKS, a autenticação não é do Kubernetes: quem bate o martelo sobre “quem é você” é o IAM da AWS. O RBAC entra depois, decidindo o que essa identidade pode fazer. Durante anos esse mapeamento viveu no ConfigMap aws-auth, que era frágil: um erro de indentação ali podia trancar todo mundo do lado de fora do cluster. Migramos para os EKS Access Entries e, sinceramente, sem dores: o vínculo “IAM role para grupo RBAC” virou recurso de API da AWS, versionável no Terraform, com políticas de acesso gerenciadas.

O exemplo abaixo usa prod-pagamentos como nome fictício, sem relação com ambiente real.

aws eks create-access-entry \
  --cluster-name prod-pagamentos \
  --principal-arn arn:aws:iam::111122223333:role/sre-team \
  --kubernetes-groups sre-admins

Na ponta da pessoa, o fluxo de login casa com o que já mostrei sobre AWS SSO com Granted: a credencial temporária do SSO assume a role, e a role cai no grupo RBAC certo. Nenhuma credencial de longa duração no meio.

Debugando “forbidden” sem sofrer

O erro clássico: Error from server (Forbidden). Meu primeiro reflexo é sempre o mesmo comando, impersonando a identidade que está falhando:

kubectl auth can-i --list \
  --as=system:serviceaccount:pagamentos:api-pagamentos \
  -n pagamentos
Resources          Non-Resource URLs   Resource Names   Verbs
selfsubjectreviews.authentication.k8s.io   []          []    [create]
selfsubjectaccessreviews.authorization.k8s.io  []      []    [create]
selfsubjectrulesreviews.authorization.k8s.io   []      []    [create]

Se a saída é só isso (os selfsubject* que toda identidade tem), a ServiceAccount não tem permissão nenhuma: o binding não existe, está no namespace errado ou o subjects aponta para outro nome. Um caso que vivi: durante uma reorganização de namespaces, um app do ArgoCD começou a falhar sync com forbidden. O application controller estava saudável, a Role existia, o YAML parecia certo. O kubectl auth can-i --as mostrou em um minuto o que meia hora de olho no YAML não mostrou: o RoleBinding tinha sido aplicado no namespace antigo. Recriar o binding no namespace novo resolveu; a lição que fica é que forbidden se debuga perguntando à API, não relendo YAML.

IRSA: quando o pod precisa falar com a AWS

Permissão dentro do cluster é RBAC; permissão para a AWS é IAM. Para um serviço que precisa ler um bucket S3 (um worker de conciliação, por exemplo), o caminho é IRSA (IAM Roles for Service Accounts): a ServiceAccount recebe uma annotation com o ARN da role IAM, e o pod troca o token dela por credenciais temporárias da AWS.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: worker-conciliacao
  namespace: conciliacao
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::111122223333:role/worker-conciliacao-s3-ro

Repare no que NÃO tem aí: nenhum RoleBinding. O worker fala com o S3, não com a API do Kubernetes, então o RBAC dele continua zerado. Least privilege dos dois lados.

Minha leitura: o melhor RBAC para humanos é quase nenhum

O senso comum trata RBAC como o exercício de criar papéis granulares para cada pessoa. Depois de operar isso em ambiente regulado, discordo: RBAC granular para gente é sintoma de gente demais dentro do cluster. O ganho real veio de tirar humanos do caminho: deploy por GitOps, acesso de exceção somente leitura, poder de escrita restrito a SRE/Cyber via grupo. De 15 admins para zero fora desses times, sem ninguém perder capacidade de trabalhar. Guarde a granularidade fina para as ServiceAccounts, que é onde as permissões de fato trabalham 24/7.

Se você está estudando para a CKA: domine os 4 objetos, saiba usar kubectl create role/rolebinding imperativo (economiza minutos preciosos) e treine kubectl auth can-i com --as. Cai prova, e cai plantão.

Leia também

Compartilhe / Share
Fernando Müller Junior
Fernando Müller Junior

SRE Manager na Appmax. 16 anos de infraestrutura, de datacenter a cloud. Escrevo sobre o que opero em produção.

Artigos: 30

Receba as notícias por email / Receive news by email

Insira seu endereço de e-mail abaixo e assine nossa newsletter / Enter your email address below and subscribe to our newsletter

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *