- Published on
Pod Security Standards - Como configurar políticas de segurança no seu cluster Kubernetes com labels em namespaces
- Authors

- Name
- Paulo Cerqueira
Antes de falar necessariamente sobre os rótulos e namespaces, é preciso entender um pouco sobre os controladores de admissão (Admission Controller), do Kubernetes.
Um controlador de admissão é um trecho de código interno (um plugin) de segurança e governança que intercepta e analisa as requisições enviadas à API Server do Kubernetets antes que os objetos sejam gravados no banco de dados do etcd. Implementado na versão v1.25 (e posteriores) do Kubernetes, ele atua após as etapas de autenticação e autorização funcionando como um guardião duplo: primeiro, ele pode alterar o conteúdo da requisição para injetar configurações padrão ou corrigir falhas (fase de mutação); depois, ele valida se o pedido cumpre todas os requisitos, políticas e restrições do cluster (fase de validação), rejeitando imediatamente qualquer configuração insegura ou fora dos padrões configurados.

Já os Padrões de Segurança de Pod do Kubernetes ( ou Pod Security Standards) são diretivas internas que definem diferentes níveis de isolamento para Pods. Esses padrões permitem que você determine como você quer restringir o comportamento dos seus pods de maneira clara e consistente. O Kubernetes oferece também um controlador de admissão de Segurança de Pod (ou Pod Security Admission ou ainda, PSA) integrado para aplicar os Padrões de Segurança de Pod. As restrições de segurança dos pods são aplicadas no nível do namespace quando os pods são criados.
Essa estratégia possibilita gerenciar políticas integradas diretamente ao ciclo de vida da API do Kubernetes sem necessidade de se utilizar recursos customizados (CRDs) de terceiros. Assim os administradores podem definir de forma simples e declarativa o nível de isolamento que cada ambiente exige.
Agora sim, rótulos e Namespaces...
Namespaces são divisões lógicas que servem para isolar, organizar e dividir recursos de um cluster Kubernetes. Além de isolamento, o controle de segurança nos Namespaces também pode ser configurado através de rótulos para aplicar os padrões de segurança de Pods (Pod Security Standards) com três políticas pré-estabelecidas: privilegiado (privileged), linha de base (baseline) e restrito (restricted) que definem várias camadas de segurança que são aplicadas pela Admissão de Segurança do Pod (Pod Security Admission).
As anotações (ou Annotations) e rótulos (ou Labels), de forma resumida, são conjuntos de chave-valor que podem ser aplicados em recursos do Kubernetes para fins de gerenciamento ou de configurações específicas do recurso em si, para injeção de configurações específicas vindas de outros recursos do Cluster (como é o caso aqui) ou para injeção de configurações de recursos customizados de terceiros (como vimos as anotações do Cert-Manager ou do Istio em outros artigos). As camadas de segurança que iremos analisar aqui são implementadas através do rótulo com a chave pod-security.kubernetes.io conforme o exemplo abaixo:
apiVersion: v1
kind: Namespace
metadata:
name: dev
labels:
pod-security.kubernetes.io/warn: baseline
pod-security.kubernetes.io/warn-version: "latest"
Os modos de configuração
O grande trunfo do rótulo pod-security.kubernetes.io está na flexibilidade de sua aplicação ao permitir a configuração de três modos de operação: warn, audit e enforce. Estes modos são aplicados de forma distinta a cada Namespace e podem ser combinados entre si.
O modo warn (Avisar) é utilizado quando se deseja alertar o usuário sobre violações de segurança, mas sem impedir a criação ou atualização do Pod. Neste modo o Kubernetes permite que o recurso seja criado, mas retorna uma mensagem de aviso diretamente no terminal:
Warning: would violate PodSecurity "restricted:latest":
allowPrivilegeEscalation != false,
unrestricted capabilities,
runAsNonRoot != true
Esse modo é muito útil em fases de adoção gradual do Pod Security Admission e permite que os times identifiquem quais cargas de trabalho ainda precisam ser ajustados antes que uma política mais rígida passe a ser aplicada de forma obrigatória.
O modo audit (Auditar) também não bloqueia a criação ou atualização do Pod, mesmo quando há violação da política. A diferença é que, em vez de focar no feedback direto ao usuário, ele registra a violação nos logs de auditoria do Kubernetes. É importante lembrar que o label audit marca a violação para auditoria, mas a utilidade prática depende de o cluster estar configurado para coletar, armazenar e encaminhar logs de auditoria. Em ambientes gerenciados, como EKS, GKE ou AKS, isso normalmente envolve integrar os logs do control plane com serviços como CloudWatch, Cloud Logging, Log Analytics, SIEMs ou stacks de observabilidade.
O audit é ideal para cenários em que o time responsável por administrar o cluster precisa entender quantos workloads seriam impactados caso a política restricted fosse aplicada, por exemplo, ou para gerar evidências de segurança sem impatar aplicações existentes.
O modo enforce (Impor), por sua vez, é o mais rígido dos três. Quando configurado, ele faz com que o Admission Controller rejeite imediatamente a criação ou atualização de Pods que violem a política definida.
Exemplo conceitual de erro, onde tentamos subir um pod de teste chamado "pod-inseguro":
Error from server (Forbidden): pods "pod-inseguro" is forbidden:
violates PodSecurity "restricted:latest":
allowPrivilegeEscalation != false,
runAsNonRoot != true,
seccompProfile
Esse comportamento acontece durante a fase de admissão da API. Ou seja, o recurso nem chega a ser criado de fato. O Kubernetes avalia o manifesto enviado ao API Server e, caso ele não esteja em conformidade com a política do namespace, a operação é bloqueada.
Esse modo é recomendado quando a organização já possui maturidade suficiente para garantir que suas cargas de trabalho atendem aos requisitos do perfil de segurança escolhido. Em produção, por exemplo, é comum usar enforce: baseline como ponto de partida e evoluir gradualmente para restricted, especialmente em cargas de trabalho que não precisam de permissões privilegiadas.
Um exemplo mais conservador seria:
apiVersion: v1
kind: Namespace
metadata:
name: producao
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
Portanto, os modos warn, audit e enforce não representam políticas diferentes, mas sim formas diferentes de reagir quando um Pod viola a política configurada. A configuração do nível de segurança é quem determina o quão restritivo será o ambiente executado naquele namespace.
As políticas de segurança
Os padrões privileged, baseline e restricted citados anteriormente, que são configurados como valores da chave pod-security.kubernetes.io, representam os níveis de segurança dos Pod Security Standards. Eles não são modos de execução, mas sim perfis de política de segurança que definem o quanto um Pod pode ou não usar recursos sensíveis do Kubernetes e do sistema operacional do nó. Esses níveis são combinados com os modos warn, audit e enforce como uma escala que permite uma configuração granular que vai do mais permissivo ao mais restritivo.
O perfil privileged (privilegiado) é o nível mais permissivo dos Pod Security Standards. Na prática, ele representa um namespace onde o Kubernetes não aplica restrições significativas de segurança sobre os Pods. Recursos alocados em namespace com este nível de acesso podem, dependendo do manifesto, solicitar acesso a recursos do host, capacidades extras do kernel Linux, namespaces do nó, volumes sensíveis e outras permissões que aproximam o container do sistema operacional real do node worker.
É importantíssmo entender que o nível privileged não significa apenas “mais permissivo”. Em muitos casos, ele significa que um container pode ter poder suficiente para impactar o próprio nó Kubernetes. Um Pod mal configurado ou comprometido nesse nível pode ter acesso a partes críticas do host, escapar parcialmente do isolamento esperado de containers ou interferir em outras cargas de trabalho.
Esse perfil é recomendável para namespaces que irão abrigar componentes de infraestrutura que realmente precisam interagir com o nó em baixo nível como plugins CNI (componentes de rede), drivers CSI (usados para integração com storages), agentes de observabilidade que precisam acessar dados do host, daemonsets de segurança ou inventário, proxies ou ferramentas que manipulam rede no nível do nó. Em ambientes reais, o ideal é que namespaces com a política privileged sejam exceções, não regra.
Já o perfil baseline (linha de base) é o ponto de equilíbrio entre segurança e compatibilidade. Ele foi pensado para bloquear configurações conhecidamente perigosas, mas sem exigir que toda aplicação seja profundamente adaptada para funcionar. Na prática, o baseline impede o uso de privilégios excessivos que normalmente não são necessários para aplicações comuns e busca evitar configurações como containers privilegiados, uso amplo de recursos do host e mecanismos óbvios de escalada de privilégio.
Esse perfil é uma boa escolha como ponto inicial para muitos ambientes de produção, porque reduz riscos importantes sem tornar o processo de implantação excessivamente difícil ou exigir muitas adequações. Aplicações web, APIs, workers, consumidores de fila, aplicações Java, Node.js, Python, Go e outras cargas de trabalho comuns geralmente conseguem funcionar com o perfil baseline com pouca ou nenhuma alteração.
O ponto forte do perfil baseline é que ele ajuda a eliminar configurações perigosas sem obrigar, logo de início, que todos os times dominem detalhes mais avançados de configuração de securityContext. Por isso, ele é muito útil para organizações que estão começando uma jornada de implantação de políticas e práticas de segurança mais restritas (hardening) em Kubernetes. Em vez de aplicar diretamente o nível mais rígido e gerar bloqueios em massa, a o time de engenharia pode, tal qual nosso exemplo acima, começar uma política de controle utilizando o perifil baseline em modo enforce e usar o perfil restricted nos modos warn e audit.
O perfil restricted (restrito), por sua vez, é o nível mais rígido dos Pod Security Standards. Ele foi criado para aplicar boas práticas fortes de segurança em Pods e reduzir a superfície de ataque dos workloads.
Enquanto o baseline bloqueia configurações obviamente perigosas, o restricted vai além e exige que os manifestos sejam explícitos sobre como o container deve executar, com foco em princípios como menor privilégio, isolamento, execução sem root e redução de capacidades do kernel.
Nesse perfil, o Kubernetes tende a exigir configurações mais endurecidas nos specs do Pod e do Container, como:
apiVersion: v1
kind: Pod
metadata:
name: app-restricted
spec:
# Aqui um exemplo de configurações de segurança do POD alinhadas à política restricted
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: nginxinc/nginx-unprivileged:latest
ports:
- containerPort: 8080
# Já aqui temos o exemplo das configurações de segurança do container
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
Esse exemplo usa uma imagem de container preparada desde a fonte para rodar sem root (nginx-unprivileged), aliada às configurações disponíveis no próprio manifesto do Kubernetes. Esse detalhe é muito importante: aplicar uma política restricted não é apenas uma configuração de Kubernetes. Muitas vezes, exige que a imagem da aplicação também esteja preparada para executar corretamente com um usuário não privilegiado.
Por exemplo, se uma aplicação tentar escrever em diretórios do sistema, abrir portas abaixo de 1024, instalar pacotes em tempo de execução ou depender do usuário root, ela pode falhar ao rodar sob o perfil restricted.
Por isso, a política do tipo restricted é excelente para cargas de trabalho mais maduras, aplicações sensíveis, ambientes regulados e plataformas que já possuem processos de boas práticas de build de imagens bem definidos. Porém, como vimos no exemplo anterior, essa política pode exigir ajustes como usar imagens que não dependam de root para funcionar, ajustar permissões de diretórios graváveis, evitar escrita em caminhos como /root, /etc ou /usr, usar portas não privilegiadas como 8080 em vez de 80, configurar corretamente securityContext no Pod e no container e remover Linux capabilities desnecessárias.
O Versionamento da política
Além dos rótulos que definem modo e nível da política, o Pod Security Admission também permite definir a versão da política que será usada na avaliação dos Pods. Aqui retornamos ao nosso último exemplo, porém um pouco mais elaborado:
apiVersion: v1
kind: Namespace
metadata:
name: producao
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/enforce-version: "1.35"
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/audit-version: "latest"
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: "latest"
A função desses rótulos é controlar qual versão dos Pod Security Standards será usada durante a validação. O Kubernetes permite usar latest ou uma versão minor específica, como v1.34, v1.35 ou v1.36, dependendo da versão suportada pelo cluster. A documentação oficial descreve que o valor deve ser uma versão minor válida do Kubernetes ou latest.
Utilizar a versão latest significa que o Kubernetes vai emitir avisos com base na versão mais recente disponível do perfil utilizado, neste caso, o perfil restricted. Esse comportamento é útil porque mantém a avaliação alinhada com as atualizações de versão do Kubernetes porém uma atualização do Kubernetes pode fazer com que novos avisos, auditorias ou bloqueios apareçam sem que os manifests da aplicação tenham mudado ou que o time de egenharia esteja plenamente preparado.
Ao se afixar uma versão específica, o Kubernetes passa a avaliar aquele modo usando os critérios de segurança associados à versão v1.35 (conforme o exemplo acima) dos Pod Security Standards. A principal vantagem desse modelo é a previsibilidade. Mesmo que o cluster seja atualizado, a política aplicada ao namespace continua presa aos critérios da versão configurada. Isso é especialmente importante em ambientes corporativos, onde mudanças de comportamento precisam passar por testes, homologação e comunicação prévia aos times de desenvolvimento.
Configuração global do Admission Controller
Em um exemplo um pouco mais prático, vamos considerar um cluster qualquer em que tenhamos 3 namespaces para a nossa aplicação, sendo eles: app-frontend, app-backend e app-plugins e que precisamos aplicar neles as mesmas políticas do manifesto acima. Para tal, podemos usar o comando kubectl label conforme abaixo:
kubectl label namespaces app-frontend app-backend app-plugins \
pod-security.kubernetes.io/enforce=baseline \
pod-security.kubernetes.io/enforce-version="1.35" \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/audit-version="latest" \
pod-security.kubernetes.io/warn=restricted \
pod-security.kubernetes.io/warn-version="latest" \
--overwrite
Repare que no comando substituímos os dois-pontos (:) pelo sinal de igual (=) para que o Kubernetes entenda a atribuição do valor à chave do rótulo.
Agora que você já sabe como configurar os manifestos dos seus namespaces novos e aplicar os rótulos nos namespaces já existentes com o kubectl, deve estar se perguntando (ou não): Mas e se eu quiser definir uma política padrão para todos os novos namespaces sem que seja preciso declarar em todos eles estes rótulos?
Pois é... Além dos labels nos namespaces, o Pod Security Admission também pode ter valores padrão configurados diretamente no Admission Controller do API Server. a configuração padrão será aplicada automaticamente pelo controle de admissão quando um novo namespace não possuir rótulos explícitos para configuração de segurança de Pods. Na configuração global, os valores de versão também podem ser latest ou uma versão específica, e caso não sejam declarados, o valor latest é utilizado como padrão.
Abaixo um exemplo de manifesto de configuração do controlador de admissão com as mesmas configurações do manifesto anterior:
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
configuration:
apiVersion: pod-security.admission.config.k8s.io/v1
kind: PodSecurityConfiguration
# Padrões aplicados quando o namespace não possui labels explícitos
# de pod-security.kubernetes.io/enforce, audit ou warn.
defaults:
enforce: "baseline"
enforce-version: "v1.35"
audit: "restricted"
audit-version: "latest"
warn: "restricted"
warn-version: "latest"
# Exceções globais.
# Requisições que se encaixarem em uma dessas exceções
# não serão avaliadas pelo Pod Security Admission.
exemptions:
usernames: []
runtimeClasses: []
namespaces:
- kube-system
Em clusters gerenciados, como EKS, GKE e AKS, nem sempre o usuário tem o mesmo nível de controle sobre a configuração direta do API Server. Por isso, na prática, o controle via labels padrão no namespace costuma ser a forma mais comum e acessível para que times de engeniaria e infraestrutura possam implementar e manter o controle das políticas de segurança sem que se haja necessidade de se adaptar manifestos ou Helm Charts para cada nova aplicação no cluster.
Tal qual nosso último exemplo, uma outra boa prática é tratar os rótulos *-version como parte da governança de upgrades do Kubernetes utilizando valores afixados no lugar de latest. Essa prática ajuda a separar duas decisões que nem sempre devem acontecer ao mesmo tempo: atualizar o cluster e mudar os critérios de segurança aplicados aos workloads.
Conclusão
A adoção do rótulo pod-security.kubernetes.io transforma e simplifica a governança em ambientes Kubernetes. Em vez de criar barreiras burocráticas complexas, esse mecanismo concede aos administradores de cluster uma ferramenta cirúrgica para aplicar o princípio do menor privilégio. Seja blindando um ambiente crítico com o modo enforce: restricted ou mapeando melhorias em ambientes legados via warn e audit, o controle de admissão por rótulos permite uma fundação de segurança robusta e acessível a qualquer nível de maturidade técnica.
Para engenheiros DevOps, uma das recomendações práticas é evitar tratar esses níveis como uma configuração isolada. Além de todas as demais boas práticas de segurança como shift-left, SAST/DAST e etc, a configuração dessas políticas devem fazer parte de uma estratégia maior de segurança da plataforma, junto com aplicação de RBAC, NetworkPolicies, políticas de admissão complementares, controle e assinatura de artefatos e boas práticas de build de containers.
O mais importante é lembrar que o Pod Security Admission não substitui as outaras camadas de segurança do Kubernetes. Ele apenas atua sobre a especificação dos Pods no momento da admissão. Ainda assim, é uma das formas mais simples, nativas e eficazes de tentar evitar ou reduzir potenciais riscos de segurança causados por manifestos permissivos demais.