O que é RBAC e por que você precisa disso?
RBAC (Role-Based Access Control) é um modelo de segurança que controla quem pode fazer o quê dentro de um cluster Kubernetes. Em vez de permitir acesso total a qualquer pessoa com credenciais válidas, o RBAC funciona como um sistema de permissões granulares: você define exatamente quais ações (verbos) um usuário ou aplicação pode executar em quais recursos.
Imagina uma empresa onde um desenvolvedor pode apenas consultar logs de pods, enquanto um administrador pode deletar recursos inteiros. Sem RBAC, ambos teriam o mesmo nível de acesso — a mesma chave do reino. Com RBAC, cada um tem apenas o que precisa. Isso não é apenas uma boa prática de segurança; é essencial em ambientes produção onde múltiplas equipes e aplicações compartilham o mesmo cluster.
ServiceAccounts: A Identidade das Aplicações
O que é um ServiceAccount?
Um ServiceAccount é a identidade que uma aplicação usa para interagir com a API do Kubernetes. Quando um pod é criado, ele recebe automaticamente um token de autenticação vinculado a um ServiceAccount. Esse token permite que o pod faça requisições autenticadas à API — por exemplo, listar outros pods, ler ConfigMaps, ou executar qualquer outra ação.
Por padrão, cada namespace possui um ServiceAccount chamado default, e todos os pods usam esse account se você não especificar outro. Porém, é uma má prática dar permissões amplas ao account padrão. O caminho correto é criar ServiceAccounts específicos com permissões mínimas — um padrão conhecido como "least privilege".
Criando um ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-deployer
namespace: production
Esse manifesto cria um ServiceAccount chamado app-deployer no namespace production. Quando aplicado com kubectl apply -f, o Kubernetes automaticamente cria um token secreto associado a esse account e o armazena em um Secret. Esse token é o que a aplicação usa para se autenticar.
Para visualizar o token gerado:
kubectl get secret -n production $(kubectl get secret -n production | grep app-deployer-token | awk '{print $1}') -o jsonpath='{.data.token}' | base64 -d
Roles e ClusterRoles: Definindo Permissões
Entendendo a Diferença
Uma Role define um conjunto de permissões (verbos) para recursos específicos dentro de um namespace. Uma ClusterRole faz exatamente a mesma coisa, mas aplica-se a todo o cluster — independentemente de namespace. A estrutura é idêntica; a diferença está no escopo.
Use Roles quando quiser restringir permissões a um único namespace. Use ClusterRoles quando a permissão precisar funcionar em todos os namespaces ou para recursos globais como Nodes e PersistentVolumes.
Exemplo: Role para Desenvolvedores
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: development
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create"]
Aqui estamos criando uma Role chamada pod-reader que permite:
- Ler (get), listar (list) e monitorar (watch) pods e seus logs
- Criar sessões de execução (exec) dentro de pods
O campo apiGroups especifica qual grupo de API os recursos pertencem. Uma string vazia significa a API core do Kubernetes. O campo resources lista o que pode ser acessado, e verbs definem as ações permitidas.
Exemplo: ClusterRole para Administradores
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-admin-custom
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list"]
Essa ClusterRole permite qualquer ação em qualquer recurso em qualquer namespace. É uma configuração perigosa e deve ser usada apenas para administradores de confiança. Note que apiGroups: ["*"] significa "todos os grupos de API" e verbs: ["*"] significa "todas as ações".
Regra Prática: Estrutura de uma Rule
Cada rule contém três elementos principais:
- apiGroups: Em qual API o recurso vive (ex:
apps,batch, string vazia para core) - resources: Quais recursos a regra aplica-se (ex:
deployments,jobs,secrets) - verbs: Quais ações são permitidas (ex:
get,list,create,delete,patch)
Existem também resourceNames (aplicar apenas a recursos específicos) e nonResourceURLs (para endpoints que não são recursos, como /healthz).
RoleBindings e ClusterRoleBindings: Conectando Identidades a Permissões
O Elo que Falta
Uma Role define o que pode ser feito. Um ServiceAccount é quem faz. Uma RoleBinding ou ClusterRoleBinding é o elo entre eles — dizendo "este ServiceAccount tem as permissões dessa Role".
Sem um binding, mesmo que você crie a melhor Role do mundo e o melhor ServiceAccount, eles não se comunicam. Um binding é obrigatório para que qualquer coisa aconteça.
Exemplo: RoleBinding em um Namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: dev-pod-reader-binding
namespace: development
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-reader
subjects:
- kind: ServiceAccount
name: developer
namespace: development
Esse RoleBinding faz o link: o ServiceAccount developer no namespace development agora tem todas as permissões definidas na Role pod-reader. O campo roleRef aponta para a Role, e subjects lista as identidades que recebem essas permissões.
Note que o namespace do binding (metadata.namespace) deve ser o mesmo da Role. Bindings são sempre limitados ao namespace onde são criados.
Exemplo: ClusterRoleBinding para Acesso Global
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: monitoring-cluster-access
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-monitor
subjects:
- kind: ServiceAccount
name: prometheus
namespace: monitoring
- kind: User
name: admin@company.com
apiGroup: rbac.authorization.k8s.io
- kind: Group
name: devops-team
apiGroup: rbac.authorization.k8s.io
Aqui estamos sendo mais ambiciosos: um ClusterRoleBinding pode conectar um ClusterRole a múltiplos tipos de sujeitos — ServiceAccounts, Users, Groups. Nesse caso, o ServiceAccount prometheus, o usuário admin@company.com e o grupo devops-team recebem as mesmas permissões em todo o cluster.
Subjects: Quem Recebe Permissões?
Um subject pode ser:
- ServiceAccount: Uma identidade de aplicação dentro do cluster
- User: Um usuário humano (geralmente gerenciado por um provedor externo como LDAP ou OIDC)
- Group: Um conjunto de usuários ou ServiceAccounts agrupados logicamente
Casos de Uso Práticos e Completos
Cenário 1: Aplicação CI/CD que Faz Deploy
Uma aplicação de CI/CD precisa criar e atualizar Deployments, mas nada mais.
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: cicd-deployer
namespace: production
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: deployer-role
namespace: production
rules:
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets"]
verbs: ["get", "list", "patch", "update"]
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: cicd-deploy-binding
namespace: production
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: deployer-role
subjects:
- kind: ServiceAccount
name: cicd-deployer
namespace: production
A aplicação CI/CD usa o token do ServiceAccount cicd-deployer para fazer patch e update em Deployments e StatefulSets, além de ler Services. Não pode criar novos recursos, deletar nada ou acessar Secrets.
Cenário 2: Sistema de Monitoramento Lendo Métricas
Uma solução de monitoramento precisa ler pods, nodes e métricas em todos os namespaces.
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: monitoring-agent
namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring-reader
rules:
- apiGroups: [""]
resources: ["nodes", "nodes/proxy", "nodes/metrics"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["services", "endpoints"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: monitoring-global-access
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: monitoring-reader
subjects:
- kind: ServiceAccount
name: monitoring-agent
namespace: monitoring
O ServiceAccount monitoring-agent pode ler métricas e informações de recursos em todo o cluster, essencial para ferramentas como Prometheus ou Grafana.
Testando e Debugando suas Permissões
Verificando o que um ServiceAccount Pode Fazer
O comando auth can-i é seu melhor amigo para debug:
# Pode o ServiceAccount 'developer' fazer 'get' em pods?
kubectl auth can-i get pods --as=system:serviceaccount:development:developer -n development
# Pode criar Deployments?
kubectl auth can-i create deployments --as=system:serviceaccount:development:developer -n development
A sintaxe system:serviceaccount:namespace:name é o formato padrão do Kubernetes para referenciar um ServiceAccount em comandos de autenticação.
Simulando Requisições da API
Para testar se a configuração funciona realmente, você pode executar um comando dentro de um pod usando o ServiceAccount:
# Entre em um pod que usa o ServiceAccount
kubectl exec -it pod-name -n namespace -- /bin/sh
# Dentro do pod, use o token para fazer requisições
TOKEN=$(cat /run/secrets/kubernetes.io/serviceaccount/token)
APISERVER=https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT
curl -H "Authorization: Bearer $TOKEN" \
--cacert /run/secrets/kubernetes.io/serviceaccount/ca.crt \
$APISERVER/api/v1/namespaces/default/pods
Se a requisição falhar com 403 Forbidden, o ServiceAccount não tem permissão. Se funcionar, você está seguro.
Auditando Permissões Atuais
Para ver todas as RoleBindings em um namespace:
kubectl get rolebindings -n production -o yaml
Para ver todas as ClusterRoleBindings globais:
kubectl get clusterrolebindings -o yaml
Analise os subjects e roleRef para entender quem tem o quê.
Boas Práticas de Segurança
Princípio do Menor Privilégio
Sempre comece com a permissão mínima necessária. Se uma aplicação precisa apenas ler Secrets, não dê permissão para deletá-los. Se precisa ler em um namespace, não use ClusterRole. Revise periodicamente e remova permissões que não são mais necessárias.
Evitar Wildcards Desnecessários
# ❌ Ruim: permite qualquer coisa
verbs: ["*"]
resources: ["*"]
apiGroups: ["*"]
# ✅ Bom: específico e restritivo
verbs: ["get", "list"]
resources: ["pods", "pods/log"]
apiGroups: [""]
Nunca Compartilhe ServiceAccounts
Cada aplicação ou componente deve ter seu próprio ServiceAccount. Isso garante que se um componente for comprometido, o atacante só terá as permissões daquele serviço.
Revise Bindings Regularmente
Crie um processo para revisar quem tem o quê. ServiceAccounts e usuários que saem da organização devem ser removidos imediatamente dos bindings.
Conclusão
Você agora entende os quatro pilares do RBAC em Kubernetes: ServiceAccounts são as identidades que executam ações; Roles e ClusterRoles definem o que pode ser feito; e RoleBindings e ClusterRoleBindings conectam essas identidades às permissões. O aprendizado prático é testar cada configuração com kubectl auth can-i antes de considerar segura. Aplique o princípio do menor privilégio — configure exatamente o que é necessário, nada mais — e você terá um cluster seguro e controlável, independentemente do tamanho ou complexidade.
Referências
- https://kubernetes.io/docs/reference/access-authn-authz/rbac/
- https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
- https://kubernetes.io/docs/reference/kubectl/generated/kubectl-auth/
- https://www.digitalocean.com/community/tutorials/how-to-inspect-kubernetes-networking
- https://brennerm.github.io/posts/rbac-in-kubernetes/