<h2>O que é RBAC e por que você precisa disso?</h2>
<p>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.</p>
<p>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.</p>
<h2>ServiceAccounts: A Identidade das Aplicações</h2>
<h3>O que é um ServiceAccount?</h3>
<p>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.</p>
<p>Por padrão, cada namespace possui um ServiceAccount chamado <code>default</code>, 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".</p>
<h3>Criando um ServiceAccount</h3>
<pre><code class="language-yaml">apiVersion: v1
kind: ServiceAccount
metadata:
name: app-deployer
namespace: production</code></pre>
<p>Esse manifesto cria um ServiceAccount chamado <code>app-deployer</code> no namespace <code>production</code>. Quando aplicado com <code>kubectl apply -f</code>, 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.</p>
<p>Para visualizar o token gerado:</p>
<pre><code class="language-bash">kubectl get secret -n production $(kubectl get secret -n production | grep app-deployer-token | awk '{print $1}') -o jsonpath='{.data.token}' | base64 -d</code></pre>
<h2>Roles e ClusterRoles: Definindo Permissões</h2>
<h3>Entendendo a Diferença</h3>
<p>Uma <strong>Role</strong> define um conjunto de permissões (verbos) para recursos específicos dentro de um namespace. Uma <strong>ClusterRole</strong> 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.</p>
<p>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.</p>
<h3>Exemplo: Role para Desenvolvedores</h3>
<pre><code class="language-yaml">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"]</code></pre>
<p>Aqui estamos criando uma Role chamada <code>pod-reader</code> que permite:</p>
<ul>
<li>Ler (<code>get</code>), listar (<code>list</code>) e monitorar (<code>watch</code>) pods e seus logs</li>
<li>Criar sessões de execução (<code>exec</code>) dentro de pods</li>
</ul>
<p>O campo <code>apiGroups</code> especifica qual grupo de API os recursos pertencem. Uma string vazia significa a API core do Kubernetes. O campo <code>resources</code> lista o que pode ser acessado, e <code>verbs</code> definem as ações permitidas.</p>
<h3>Exemplo: ClusterRole para Administradores</h3>
<pre><code class="language-yaml">apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-admin-custom
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list"]</code></pre>
<p>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 <code>apiGroups: ["<em>"]</code> significa "todos os grupos de API" e <code>verbs: ["</em>"]</code> significa "todas as ações".</p>
<h3>Regra Prática: Estrutura de uma Rule</h3>
<p>Cada rule contém três elementos principais:</p>
<ol>
<li><strong>apiGroups</strong>: Em qual API o recurso vive (ex: <code>apps</code>, <code>batch</code>, string vazia para core)</li>
<li><strong>resources</strong>: Quais recursos a regra aplica-se (ex: <code>deployments</code>, <code>jobs</code>, <code>secrets</code>)</li>
<li><strong>verbs</strong>: Quais ações são permitidas (ex: <code>get</code>, <code>list</code>, <code>create</code>, <code>delete</code>, <code>patch</code>)</li>
</ol>
<p>Existem também <code>resourceNames</code> (aplicar apenas a recursos específicos) e <code>nonResourceURLs</code> (para endpoints que não são recursos, como <code>/healthz</code>).</p>
<h2>RoleBindings e ClusterRoleBindings: Conectando Identidades a Permissões</h2>
<h3>O Elo que Falta</h3>
<p>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".</p>
<p>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.</p>
<h3>Exemplo: RoleBinding em um Namespace</h3>
<pre><code class="language-yaml">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</code></pre>
<p>Esse RoleBinding faz o link: o ServiceAccount <code>developer</code> no namespace <code>development</code> agora tem todas as permissões definidas na Role <code>pod-reader</code>. O campo <code>roleRef</code> aponta para a Role, e <code>subjects</code> lista as identidades que recebem essas permissões.</p>
<p>Note que o namespace do binding (<code>metadata.namespace</code>) deve ser o mesmo da Role. Bindings são sempre limitados ao namespace onde são criados.</p>
<h3>Exemplo: ClusterRoleBinding para Acesso Global</h3>
<pre><code class="language-yaml">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</code></pre>
<p>Aqui estamos sendo mais ambiciosos: um ClusterRoleBinding pode conectar um ClusterRole a múltiplos tipos de sujeitos — ServiceAccounts, Users, Groups. Nesse caso, o ServiceAccount <code>prometheus</code>, o usuário <code>admin@company.com</code> e o grupo <code>devops-team</code> recebem as mesmas permissões em todo o cluster.</p>
<h3>Subjects: Quem Recebe Permissões?</h3>
<p>Um subject pode ser:</p>
<ul>
<li><strong>ServiceAccount</strong>: Uma identidade de aplicação dentro do cluster</li>
<li><strong>User</strong>: Um usuário humano (geralmente gerenciado por um provedor externo como LDAP ou OIDC)</li>
<li><strong>Group</strong>: Um conjunto de usuários ou ServiceAccounts agrupados logicamente</li>
</ul>
<h2>Casos de Uso Práticos e Completos</h2>
<h3>Cenário 1: Aplicação CI/CD que Faz Deploy</h3>
<p>Uma aplicação de CI/CD precisa criar e atualizar Deployments, mas nada mais.</p>
<pre><code class="language-yaml">---
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</code></pre>
<p>A aplicação CI/CD usa o token do ServiceAccount <code>cicd-deployer</code> 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.</p>
<h3>Cenário 2: Sistema de Monitoramento Lendo Métricas</h3>
<p>Uma solução de monitoramento precisa ler pods, nodes e métricas em todos os namespaces.</p>
<pre><code class="language-yaml">---
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</code></pre>
<p>O ServiceAccount <code>monitoring-agent</code> pode ler métricas e informações de recursos em todo o cluster, essencial para ferramentas como Prometheus ou Grafana.</p>
<h2>Testando e Debugando suas Permissões</h2>
<h3>Verificando o que um ServiceAccount Pode Fazer</h3>
<p>O comando <code>auth can-i</code> é seu melhor amigo para debug:</p>
<pre><code class="language-bash"># 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</code></pre>
<p>A sintaxe <code>system:serviceaccount:namespace:name</code> é o formato padrão do Kubernetes para referenciar um ServiceAccount em comandos de autenticação.</p>
<h3>Simulando Requisições da API</h3>
<p>Para testar se a configuração funciona realmente, você pode executar um comando dentro de um pod usando o ServiceAccount:</p>
<pre><code class="language-bash"># 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</code></pre>
<p>Se a requisição falhar com 403 Forbidden, o ServiceAccount não tem permissão. Se funcionar, você está seguro.</p>
<h3>Auditando Permissões Atuais</h3>
<p>Para ver todas as RoleBindings em um namespace:</p>
<pre><code class="language-bash">kubectl get rolebindings -n production -o yaml</code></pre>
<p>Para ver todas as ClusterRoleBindings globais:</p>
<pre><code class="language-bash">kubectl get clusterrolebindings -o yaml</code></pre>
<p>Analise os <code>subjects</code> e <code>roleRef</code> para entender quem tem o quê.</p>
<h2>Boas Práticas de Segurança</h2>
<h3>Princípio do Menor Privilégio</h3>
<p>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.</p>
<h3>Evitar Wildcards Desnecessários</h3>
<pre><code class="language-yaml"></code></pre>
<h3>Nunca Compartilhe ServiceAccounts</h3>
<p>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.</p>
<h3>Revise Bindings Regularmente</h3>
<p>Crie um processo para revisar quem tem o quê. ServiceAccounts e usuários que saem da organização devem ser removidos imediatamente dos bindings.</p>
<h2>Conclusão</h2>
<p>Você agora entende os quatro pilares do RBAC em Kubernetes: <strong>ServiceAccounts</strong> são as identidades que executam ações; <strong>Roles e ClusterRoles</strong> definem o que pode ser feito; e <strong>RoleBindings e ClusterRoleBindings</strong> conectam essas identidades às permissões. O aprendizado prático é testar cada configuração com <code>kubectl auth can-i</code> 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.</p>
<h2>Referências</h2>
<ul>
<li>https://kubernetes.io/docs/reference/access-authn-authz/rbac/</li>
<li>https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/</li>
<li>https://kubernetes.io/docs/reference/kubectl/generated/kubectl-auth/</li>
<li>https://www.digitalocean.com/community/tutorials/how-to-inspect-kubernetes-networking</li>
<li>https://brennerm.github.io/posts/rbac-in-kubernetes/</li>
</ul>
<p><!-- FIM --></p>