Skip to main content

Aplicando o princípio do menor privilégio ao Kubernetes com RBAC

Escrito por
Headshot of Jekayin-Oluwa Olabemiwo

Jekayin-Oluwa Olabemiwo

feature kubernetes polp

29 de agosto de 2022

0 minutos de leitura

O que é o princípio do menor privilégio?

O princípio do menor privilégio (PoLP) é uma estratégia de defesa no desenvolvimento de software. Também chamado de princípio do privilégio mínimo ou princípio da autoridade mínima, o PoLP garante que os usuários só possam acessar os sistemas, processos, redes e arquivos necessários para concluir as tarefas que lhes foram atribuídas.

Quando configurado corretamente, usuários não autorizados não conseguem acessar funções restritas do aplicativo nem trocar de função. Além disso, não conseguem acessar determinados dados, como arquivos e segredos de API — a menos que isso seja necessário para concluir uma tarefa atribuída. Isso ajuda a proteger contra consequências intencionais e não intencionais de ações não autorizadas.

Em instalações físicas, o acesso a determinadas áreas, como salas de servidores, é restrito a funcionários autorizados a trabalhar nesses locais. Algumas áreas críticas dessas instalações só podem ser acessadas por integrantes experientes ou seniores das equipes relacionadas.

A mesma lógica se aplica ao PoLP. Por exemplo, em um software de gestão de funcionários, é provável que apenas profissionais de RH tenham acesso aos registros dos colaboradores. Da mesma forma, determinadas ações — como implantar versões de aplicativos em produção — podem ser configuradas para que apenas engenheiros seniores possam executá-las.

O PoLP também está presente em aplicativos de software como serviço (SaaS), nos quais os usuários têm diferentes funções, de acordo com as tarefas que realizam.

Proteger sistemas de software exige equilibrar a necessidade de evitar restrições excessivas para as partes interessadas e impedir que o sistema fique vulnerável a agentes mal-intencionados. O PoLP ajuda a alcançar esse equilíbrio, mantendo o sistema seguro e reduzindo os obstáculos relacionados ao acesso.

Além disso, o PoLP ajuda a manter operações eficientes e confiáveis. Os sistemas ficam menos sujeitos a interrupções causadas por ataques de malware ou por atividades arriscadas dos usuários, como enviar código inseguro para produção ou alterar senhas de administrador.

Neste artigo, vamos explorar como o Kubernetes (K8s) oferece suporte ao PoLP por meio da implementação do controle de acesso baseado em função.

Aplicando o princípio do menor privilégio ao acesso ao Kubernetes

O Kubernetes gerencia cargas de trabalho de orquestração de contêineres. Ele oferece uma plataforma para que organizações e desenvolvedores automatizem a implantação, o gerenciamento e o dimensionamento de aplicativos em contêineres. Isso significa que vários integrantes das equipes de desenvolvimento, operações e TI precisam acessar um ambiente Kubernetes para criar ou manter aplicativos implantados.

Para garantir a segurança ideal e proteger os recursos, as organizações precisam seguir o PoLP ao usar o Kubernetes, independentemente da etapa atual de produção. Felizmente, o Kubernetes oferece mecanismos de autenticação e autorização para controlar o acesso. As equipes devem definir explicitamente quem pode acessar quais recursos operacionais e permissões ao interagir com a API do Kubernetes. Além disso, as organizações devem desativar o acesso não autenticado, seja por contas de usuários ou de serviços.

Como o Kubernetes gerencia o acesso com RBAC

O controle de acesso baseado em função (RBAC) é um método usado em muitos sistemas para definir permissões de recursos com base nas funções das pessoas no ambiente. O Kubernetes conta com um mecanismo nativo de RBAC abrangente, que permite configurar permissões para especificar como um usuário ou grupo de usuários pode interagir com qualquer objeto do Kubernetes em um cluster. Usar esse framework de RBAC é o primeiro passo para proteger um cluster e seus aplicativos em contêineres.

Os objetos do Kubernetes são entidades persistentes que especificam quais aplicativos em contêineres estão em execução, seus recursos e as políticas que orientam o funcionamento desses aplicativos. Em essência, eles definem o estado desejado do cluster. É possível criar, alterar ou excluir objetos usando a API do Kubernetes.

No Kubernetes, há dois tipos de contas: de usuários e de serviços. As contas de usuários são destinadas a pessoas que usam o sistema, enquanto as contas de serviços são destinadas aos processos que acessam a API do Kubernetes. O RBAC do Kubernetes controla o acesso dessas contas aos recursos, incluindo pods, segredos, controladores e definições de recursos personalizados (CRDs).

No Kubernetes, as permissões são definidas com objetos Role ou ClusterRole. Em seguida, as permissões definidas são atribuídas como regras usando os objetos RoleBinding e ClusterRoleBinding. A API RBAC define os quatro tipos de objetos do Kubernetes a seguir:

  • Role — gerencia as permissões aplicáveis aos recursos de um único namespace

  • ClusterRole — gerencia as permissões aplicáveis a todo um cluster

  • RoleBinding — atribui uma Role a uma conta ou grupo em um namespace específico

  • ClusterRoleBinding — atribui uma ClusterRole a uma conta ou grupo em todos os namespaces do cluster

Nas próximas duas seções, vamos explorar como as políticas de RBAC se alinham ao PoLP para limitar o acesso aos recursos dos clusters.

Definindo permissões

Para configurar as permissões corretamente, você precisa configurar o Kubernetes para refletir a função de cada integrante da equipe, levando em conta as práticas de PoLP. Usar Roles e ClusterRoles é uma maneira muito eficiente de fazer isso. As Roles se aplicam aos recursos de um namespace, enquanto as ClusterRoles se aplicam aos recursos de todo o cluster.

Nesta seção, vamos explorar como restringir o acesso a determinadas partes de um sistema com Role e ClusterRole.

Imagine que uma empresa contratou um novo engenheiro DevOps sênior que precisa visualizar todas as variáveis de ambiente e outros segredos, enquanto os demais integrantes da equipe não devem ter esse acesso. Além disso, como integrante da equipe de operações, esse engenheiro talvez precise visualizar os pods criados para as cargas de trabalho dos aplicativos da empresa e monitorar a integridade dos contêineres que hospedam os aplicativos voltados ao cliente.

Para fazer isso, comece definindo os objetos Role e ClusterRole no arquivo YAML. Veja um exemplo de como definir uma Role para permitir acesso de leitura aos segredos no namespace de desenvolvimento:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: development
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

O código acima especifica a versão da API. O RBAC usa o grupo de APIs rbac.authorization.k8s.io para configurar políticas de autorização pela API do Kubernetes. Em seguida, especifica o tipo de definição como Role e indica o namespace ao qual ela se aplica — development. Isso pressupõe que development seja o namespace dos recursos usados pela equipe de desenvolvimento. Depois, a Role recebe o nome secretpod-reader.

A seção rules contém os recursos aos quais a regra se aplica e as ações que a Role pode executar nesses recursos. Essa seção também inclui alguns verbos de regra. O Kubernetes usa verbos como write, watch, read e delete para gerenciar permissões em categorias amplas.

Veja a seguir como definir uma ClusterRole para permitir acesso de leitura aos pods de front-end do cluster:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"

Observe que o código acima não especifica o namespace nos metadados, pois as ClusterRoles não pertencem a namespaces. Portanto, na seção de metadados, você especificou apenas o nome da ClusterRole: pod-reader.

Em seguida, você pode vincular a Role ao grupo de recursos no namespace de desenvolvimento e vincular a ClusterRole ao cluster. Agora, sua equipe — e mais ninguém — pode visualizar os segredos necessários nos recursos de desenvolvimento. Aplicar o PoLP dessa forma permite que sua equipe acesse o que precisa para realizar tarefas de desenvolvimento, mas impede que outras pessoas da organização acessem esses pods e recursos.

Agora você criou uma Role para permitir que o engenheiro DevOps acesse segredos e uma ClusterRole para que toda a equipe de DevOps leia os pods. Na próxima seção, você vai atribuir permissões à Role e à ClusterRole.

Atribuindo permissões

A vinculação de uma Role é útil, por exemplo, quando um funcionário específico precisa acessar as chaves secretas usadas na configuração de um aplicativo. Elas podem ser pares de chaves de API ou variáveis de ambiente.

Além disso, precisamos usar a vinculação de cluster para conceder permissões em todo o cluster. Ela pode permitir que qualquer usuário da ClusterRole especificada leia os pods em qualquer namespace, independentemente do namespace.

Se o engenheiro DevOps for um usuário chamado Sola, você poderá atribuir a Role criada acima ao usuário sola no namespace de desenvolvimento. Assim, sola poderá ler os segredos desse namespace.

Observe que o nome sola diferencia maiúsculas de minúsculas. A definição de RoleBinding é a seguinte:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: secret-reader
  namespace: development
subjects:
- kind: User
  name: sola
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: secret-reader 
  apiGroup: rbac.authorization.k8s.io

No código acima, você:

  • Especificou o tipo RoleBinding.

  • Especificou uma Role chamada secret-reader e o namespace development ao qual a RoleBinding se aplica.

  • Especificou sola como User na seção subjects. Você também pode especificar vários sujeitos.

  • Anexou a Role correspondente à vinculação na seção roleRef. Lembre-se de que, depois de criar uma vinculação, não é possível alterar a Role ou ClusterRole anexada a ela na seção roleRef.

O exemplo de RoleBinding acima atende a casos de uso em que um integrante específico da equipe de desenvolvimento precisa acessar as chaves secretas usadas na configuração de aplicativos — como pares de chaves de API e variáveis de ambiente.

Daqui em diante, você precisa usar ClusterBinding para conceder permissões em todo um cluster. No exemplo a seguir, você verá como usar ClusterBinding para permitir que qualquer usuário do grupo ops leia os pods em qualquer namespace do cluster. Observe que o nome ops diferencia maiúsculas de minúsculas:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-pods-global
subjects:
- kind: Group
  name: ops
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

A vinculação de cluster é útil em situações como a do exemplo acima, em que precisamos conceder a todos os integrantes da equipe permissão para acessar todos os pods do cluster. Com cada permissão específica configurada corretamente, os usuários do grupo podem visualizar os pods e avaliar seu estado, garantindo que consigam concluir os relatórios exigidos e suas responsabilidades de monitoramento.Ao mesmo tempo, as definições da ClusterRole garantem que esses usuários não possam modificar os pods nem os aplicativos que eles contêm.

Protegendo suas configurações do K8

O controle de acesso baseado em função pode contribuir muito para aplicar o princípio do menor privilégio. Felizmente, o framework nativo de RBAC do Kubernetes oferece recursos abrangentes nessa área. A possibilidade de criar e vincular funções é muito eficaz para garantir que apenas o número mínimo de usuários tenha o acesso necessário aos recursos. Isso reduz a exposição a possíveis agentes mal-intencionados sem impedir que os integrantes da equipe exerçam suas funções. Para ver um exemplo de como usamos o RBAC do Kubernetes na Snyk.

Para saber mais sobre como implementar o PoLP de forma correta e segura no seu ambiente Kubernetes, acesse a Snyk e confira outras publicações no blog da Snyk.

Recursos do Kubernetes:

Segurança de contêineres que prioriza os desenvolvedores

O Snyk encontra e corrige automaticamente vulnerabilidades em imagens de contêiner e workloads do Kubernetes.