RBAC em Kubernetes: Roles, ClusterRoles, Bindings e ServiceAccounts na Prática Já leu

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

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:

  1. apiGroups: Em qual API o recurso vive (ex: apps, batch, string vazia para core)
  2. resources: Quais recursos a regra aplica-se (ex: deployments, jobs, secrets)
  3. 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/

Artigos relacionados