Pular para o conteúdo

Dar acesso mínimo a um time no cluster

Intermediário14 min de leituraseguranca

O pedido chega como “preciso de acesso ao cluster” e a resposta preguiçosa é cluster-admin. Este guia mostra o caminho de dez minutos que entrega o acesso útil sem entregar o cluster.

Comece pela tarefa, não pelo verbo. Um time de produto tipicamente precisa:

Tarefa Recursos Verbos
Ver o que está rodando pods, deployments, services get, list, watch
Ler logs pods/log get, list
Diagnosticar events, describe, pods/exec* get, list, create*
Reiniciar um serviço deployments, pods patch, delete
Ajustar configuração configmaps get, list, create, update

E não precisa: nós, CRDs, ClusterRoleBindings, namespaces de terceiros, nem Secrets — leitura de Secret é leitura de senha de banco. Se a aplicação usa o Secret, o Pod usa; a pessoa não precisa.

pods/exec merece decisão consciente: dá shell dentro do container, com o que estiver montado ali. Libere em desenvolvimento, restrinja em produção — e prefira kubectl debug com container efêmero para diagnóstico.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata: { name: time-loja-operacao, namespace: loja }
rules:
- apiGroups: [""]
resources: [pods, services, configmaps, events, endpoints]
verbs: [get, list, watch]
- apiGroups: [""]
resources: [pods/log]
verbs: [get, list]
- apiGroups: [apps]
resources: [deployments, replicasets, statefulsets]
verbs: [get, list, watch, patch] # patch cobre rollout restart
- apiGroups: [apps]
resources: [deployments/scale]
verbs: [get, update, patch]
- apiGroups: [""]
resources: [pods]
verbs: [delete] # reiniciar Pod individual
# secrets deliberadamente ausentes

Para leitura ampla sem escrita, aproveite os papéis embutidos em vez de reescrever: view (não lê Secrets), edit (escreve, inclui Secrets) e admin (gerencia RBAC do namespace). O view é um ótimo ponto de partida para produção.

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata: { name: time-loja, namespace: loja }
subjects:
- kind: Group
name: "time-loja" # vem do provedor de identidade (OIDC, IAM, Entra)
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: time-loja-operacao
apiGroup: rbac.authorization.k8s.io

Vincular a pessoas gera um passivo: quem sai da empresa continua no YAML, e quem entra depende de alguém lembrar. Com grupo, a entrada e a saída acontecem no provedor de identidade, que já tem o processo de desligamento.

Janela do terminal
# simule as ações do time
kubectl auth can-i get pods -n loja --as-group=time-loja [email protected]
kubectl auth can-i get secrets -n loja --as-group=time-loja [email protected] # deve ser "no"
kubectl auth can-i delete pods -n producao --as-group=time-loja [email protected]
kubectl auth can-i --list -n loja --as-group=time-loja [email protected]

Teste também o negativo: o acesso está correto quando o que deveria ser negado é negado. Peça para alguém do time fazer a tarefa real e reporte o que faltou — é mais rápido que adivinhar.

Aproveite para achar o excesso acumulado:

Janela do terminal
# quem tem cluster-admin
kubectl get clusterrolebindings -o json | jq -r '.items[]
| select(.roleRef.name=="cluster-admin")
| "\(.metadata.name): \(.subjects // [] | map(.kind+"/"+.name) | join(", "))"'
# ServiceAccounts com poderes amplos
kubectl get clusterrolebindings -o json | jq -r '.items[]
| select(.subjects // [] | any(.kind=="ServiceAccount"))
| "\(.roleRef.name)\t\(.subjects[].namespace)/\(.subjects[].name)"' | sort -u

Alvos típicos de limpeza: pipeline com cluster-admin, operador de terceiro com permissão ampla, e binding de uma pessoa que saiu há dois anos.

  • Trimestral: quem tem acesso a produção, e por quê.
  • A cada desligamento: remoção do grupo no provedor de identidade (não no cluster).
  • RBAC versionado no Git e aplicado por GitOps — mudança de permissão passa a ter revisão.
  • Alerta em criação de ClusterRoleBinding novo.
Sintoma Causa provável
Forbidden em recurso esperado Falta o apiGroup correto (apps vs "")
kubectl get all incompleto Normal: all não cobre tudo; peça o recurso pelo nome
Acesso funciona para um e não para outro O grupo não chega no token do provedor de identidade
Consegue ver Secrets sem querer Papel edit ou admin concedido no lugar de view
Precisa acessar dois namespaces Duas RoleBindings — evite ClusterRole por conveniência
Janela do terminal
kubectl auth whoami # quais grupos o seu token realmente carrega
  • Lista de tarefas reais antes da lista de verbos.
  • Role por namespace, sem secrets e sem recursos de cluster.
  • RoleBinding para grupo do provedor de identidade.
  • Testes positivos e negativos com auth can-i.
  • Auditoria de cluster-admin feita e reduzida.
  • Manifests versionados e aplicados por GitOps.
  • Revisão trimestral agendada.