<h2>Pod Security Standards no Kubernetes: Proteção em Camadas</h2>
<p>Pod Security Standards (PSS) é um mecanismo nativo do Kubernetes que define três níveis de restrição de segurança para Pods. Diferente de políticas antigas como Pod Security Policy (descontinuada desde a v1.25), o PSS utiliza admission controllers e labels nos namespaces para regular o que cada Pod pode fazer. Essa abordagem elimina complexidades anteriores e oferece uma solução simples mas robusta.</p>
<p>O Kubernetes, por padrão, permite que containers rodem com privilégios elevados, acessem filesystems do host, e façam operações perigosas. O PSS resolve esse problema estabelecendo três perfis: <strong>Restricted</strong> (máxima segurança), <strong>Baseline</strong> (segurança mínima compatível com padrões), e <strong>Privileged</strong> (sem restrições). Cada um deles é aplicado no nível do namespace, não requerendo instalação de recursos externos.</p>
<h2>Os Três Níveis de Segurança</h2>
<h3>Restricted: Máxima Segurança</h3>
<p>O nível <strong>Restricted</strong> implementa as melhores práticas de segurança conforme recomendações da indústria. Um Pod sob este padrão não pode rodar como root, não pode acessar o filesystem do host, não pode escalar privilégios, e deve declarar limites de recursos. É ideal para ambientes críticos e produção.</p>
<p>As principais restrições do Restricted incluem:</p>
<ul>
<li>Containers devem rodar com <code>runAsNonRoot: true</code></li>
<li>Linux capabilities devem ser removidas (exceto NET_BIND_SERVICE)</li>
<li>Filesystem raiz deve ser somente-leitura (<code>readOnlyRootFilesystem: true</code>)</li>
<li>Não é permitido <code>privileged: true</code> ou <code>allowPrivilegeEscalation: true</code></li>
<li><code>seccomp</code> deve ser configurado com <code>RuntimeDefault</code> ou um perfil customizado</li>
<li>SELinux deve usar <code>restricted</code> como tipo</li>
</ul>
<p>Aqui está um exemplo de um Deployment que está em conformidade com o Restricted:</p>
<pre><code class="language-yaml">apiVersion: apps/v1
kind: Deployment
metadata:
name: secure-app
namespace: production
spec:
replicas: 2
selector:
matchLabels:
app: secure-app
template:
metadata:
labels:
app: secure-app
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: nginx:1.21-alpine
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
capabilities:
drop:
- ALL
ports:
- containerPort: 8080
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "500m"
volumeMounts:
- name: cache
mountPath: /tmp
- name: var-cache
mountPath: /var/cache/nginx
volumes:
- name: cache
emptyDir: {}
- name: var-cache
emptyDir: {}</code></pre>
<h3>Baseline: Segurança Mínima Viável</h3>
<p>O <strong>Baseline</strong> representa o nível mínimo de segurança sem restringir aplicações legadas comuns. Ele permite muitas operações que o Restricted proíbe, mas ainda bloqueia os riscos mais óbvios como containers com ALL capabilities ou hosts que usam privilégios inseguros do host. É apropriado para aplicações que você conhece e confia, mas que não podem cumprir os requisitos do Restricted.</p>
<p>As principais características do Baseline:</p>
<ul>
<li>Permite <code>runAsRoot</code> (usuário 0), mas bloqueia alguns casos privilegiados</li>
<li>Permite a maioria das Linux capabilities, exceto SYS_ADMIN, SYS_RAWIO, etc.</li>
<li>Não requer <code>readOnlyRootFilesystem</code></li>
<li>Permite <code>allowPrivilegeEscalation: true</code></li>
<li>Não força seccomp ou SELinux</li>
</ul>
<p>Um exemplo típico de aplicação Baseline:</p>
<pre><code class="language-yaml">apiVersion: v1
kind: Pod
metadata:
name: legacy-app
namespace: development
spec:
containers:
- name: web-server
image: apache:2.4
securityContext:
runAsUser: 0
allowPrivilegeEscalation: true
ports:
- containerPort: 80
volumeMounts:
- name: www
mountPath: /var/www/html
volumes:
- name: www
hostPath:
path: /data/www
type: Directory</code></pre>
<p>Este Pod funcionará sob o Baseline, mas falhará no Restricted porque executa como root e permite escalação de privilégios.</p>
<h3>Privileged: Sem Restrições</h3>
<p>O nível <strong>Privileged</strong> desabilita completamente as verificações de segurança do PSS. É necessário apenas em casos muito específicos: container runtimes, CNI plugins, ou ferramentas de monitoramento do host que genuinamente precisam de acesso privilegiado. Você deve evitar este nível para aplicações normais.</p>
<p>Um exemplo de uso legítimo do Privileged seria um daemonset que monitora o host:</p>
<pre><code class="language-yaml">apiVersion: apps/v1
kind: DaemonSet
metadata:
name: host-monitor
namespace: kube-system
spec:
selector:
matchLabels:
app: host-monitor
template:
metadata:
labels:
app: host-monitor
spec:
hostNetwork: true
hostPID: true
containers:
- name: monitor
image: prometheus-node-exporter:latest
securityContext:
privileged: true
volumeMounts:
- name: proc
mountPath: /host/proc
readOnly: true
- name: sys
mountPath: /host/sys
readOnly: true
volumes:
- name: proc
hostPath:
path: /proc
- name: sys
hostPath:
path: /sys</code></pre>
<h2>Aplicando Pod Security Standards aos Namespaces</h2>
<p>Para ativar o Pod Security Standards em um namespace, você usa labels. Existem três tipos de labels que controlam o comportamento do enforcement:</p>
<ul>
<li><code>pod-security.kubernetes.io/enforce</code>: bloqueia Pods que violam o padrão (modo enforcement)</li>
<li><code>pod-security.kubernetes.io/audit</code>: registra Pods que violam, mas permite (modo auditoria)</li>
<li><code>pod-security.kubernetes.io/warn</code>: avisa o usuário mas permite (modo warning)</li>
</ul>
<p>Cada um desses labels recebe um valor: <code>baseline</code>, <code>restricted</code> ou <code>privileged</code>.</p>
<h3>Configurando um Namespace com Restricted</h3>
<p>Para forçar que todos os Pods em um namespace sigam o padrão Restricted:</p>
<pre><code class="language-yaml">apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted</code></pre>
<p>Depois de aplicar este namespace, qualquer tentativa de criar um Pod que não esteja em conformidade com Restricted resultará em um erro. Por exemplo, tentar criar um Pod que roda como root será rejeitado:</p>
<pre><code class="language-bash">$ kubectl apply -f pod-root.yaml -n production
Error from server (Forbidden): error when creating "pod-root.yaml": pods "test-pod" is forbidden:
violates PodSecurityPolicy: runAsNonRoot</code></pre>
<h3>Modo Auditoria e Warning</h3>
<p>Se você quer migrar gradualmente para padrões mais restritos, use auditoria e warnings primeiro:</p>
<pre><code class="language-yaml">apiVersion: v1
kind: Namespace
metadata:
name: staging
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted</code></pre>
<p>Nesta configuração, Pods podem violar o Restricted, mas:</p>
<ul>
<li>Serão registrados nos logs de auditoria</li>
<li>Exibirão um aviso ao usuário</li>
<li>Mas ainda serão criados com sucesso</li>
</ul>
<p>Isso permite identificar quais aplicações precisam de ajustes antes de enforçar Restricted completamente.</p>
<h3>Exceções com Versões de API</h3>
<p>O PSS evolui com novas versões do Kubernetes. Use labels de versão para aceitar comportamentos antigos:</p>
<pre><code class="language-yaml">apiVersion: v1
kind: Namespace
metadata:
name: legacy-support
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/enforce-version: v1.24
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/audit-version: latest</code></pre>
<h2>Migração Prática: Do Privileged para Restricted</h2>
<p>Uma estratégia real de migração segue passos claros. Começamos examinando Pods existentes, aplicamos labels de auditoria, identificamos violações, corrigimos manifests, e finalmente ativamos enforcement.</p>
<h3>Passo 1: Auditar Aplicações Existentes</h3>
<p>Aplique auditoria sem enforcement em namespaces importantes:</p>
<pre><code class="language-bash">kubectl label namespace my-app \
pod-security.kubernetes.io/audit=restricted \
--overwrite</code></pre>
<h3>Passo 2: Identificar Violações</h3>
<p>Verifique os logs de auditoria para encontrar quais Pods violam o padrão:</p>
<pre><code class="language-bash">kubectl get events -n my-app --sort-by='.lastTimestamp' | grep "PodSecurity"</code></pre>
<h3>Passo 3: Corrigir Manifests</h3>
<p>Para cada aplicação que viola, atualize o manifest. Exemplo de correção de uma aplicação que roda como root:</p>
<p><strong>Antes (violação):</strong></p>
<pre><code class="language-yaml">containers:
- name: app
image: myapp:latest</code></pre>
<p><strong>Depois (correto):</strong></p>
<pre><code class="language-yaml">securityContext:
runAsNonRoot: true
runAsUser: 1001
fsGroup: 2001
containers:
- name: app
image: myapp:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL</code></pre>
<h3>Passo 4: Ativar Enforcement</h3>
<p>Apenas depois que todas as aplicações foram testadas e corrigidas:</p>
<pre><code class="language-bash">kubectl label namespace my-app \
pod-security.kubernetes.io/enforce=restricted \
--overwrite</code></pre>
<h2>Conclusão</h2>
<p>Aprendemos que <strong>Pod Security Standards oferece três níveis distintos</strong> — Restricted para máxima segurança, Baseline para compatibilidade, e Privileged para casos raros — sem complexidades de gerenciamento de políticas externas. <strong>A aplicação é simples</strong>: use labels no namespace e o admission controller nativo do Kubernetes garante conformidade. <strong>A migração é gradual e segura</strong>: implemente auditoria primeiro, identifique problemas, corrija Pods, então enforce — permitindo transições sem downtime.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://kubernetes.io/docs/concepts/security/pod-security-standards/" target="_blank" rel="noopener noreferrer">Pod Security Standards - Documentação Oficial Kubernetes</a></li>
<li><a href="https://kubernetes.io/docs/tasks/configure-pod-container/enforce-standards-admission-controller/" target="_blank" rel="noopener noreferrer">Pod Security Standards - Guia de Admission Controller</a></li>
<li><a href="https://kubernetes.io/docs/concepts/security/pod-security-policy/" target="_blank" rel="noopener noreferrer">Kubernetes Security Best Practices</a></li>
<li><a href="https://kubernetes.io/docs/tasks/configure-pod-container/security-context/" target="_blank" rel="noopener noreferrer">Linux Capabilities and Security Contexts in Kubernetes</a></li>
<li><a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#securitycontext-v1-core" target="_blank" rel="noopener noreferrer">Kubernetes Official API Documentation - SecurityContext</a></li>
</ul>
<p><!-- FIM --></p>