DevOps Mind
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.ioA 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:
- 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.
- 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. - 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-adminsNa 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 pagamentosResources 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-roRepare 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.








