Política como código
“Todo bucket precisa ser privado” escrito em uma página de wiki é uma intenção. A mesma frase como código executável é uma garantia: ela roda no pull request, roda na admissão do cluster e diz exatamente qual recurso está fora da regra e por quê.
Política como código também resolve o problema humano de segurança: ninguém precisa lembrar de tudo, e a revisão deixa de ser o gargalo.
Onde a política roda
Seção intitulada “Onde a política roda”O mesmo requisito costuma precisar de dois pontos de aplicação:
- No CI, sobre o plano ou o manifest — feedback rápido, antes do merge, com a pessoa que pode corrigir.
- Na admissão, no cluster ou na nuvem — barreira final, que pega o que não passou pelo pipeline (aplicação manual, controlador, operador).
Só CI é contornável; só admissão é frustrante, porque o erro aparece tarde. Use os dois, com a mesma regra versionada.
Kyverno para Kubernetes
Seção intitulada “Kyverno para Kubernetes”Kyverno expressa políticas em YAML, o que reduz muito a barreira de entrada em ambiente Kubernetes. Ele valida, muta (corrige o recurso na admissão) e gera recursos.
apiVersion: kyverno.io/v1kind: ClusterPolicymetadata: { name: exigir-limites-e-nao-root }spec: validationFailureAction: Audit # comece aqui; troque para Enforce depois background: true # avalia também o que já existe rules: - name: limites-obrigatorios match: { any: [{ resources: { kinds: [Pod] } }] } exclude: { any: [{ resources: { namespaces: [kube-system] } }] } validate: message: "Todo container precisa declarar requests e limits de memória." pattern: spec: containers: - resources: requests: { memory: "?*" } limits: { memory: "?*" } - name: sem-root match: { any: [{ resources: { kinds: [Pod] } }] } validate: message: "Containers não podem rodar como root." pattern: spec: =(securityContext): =(runAsNonRoot): truekubectl kyverno apply politicas/ --resource manifests/ # no CI, antes do mergekubectl get policyreport -A # o que já está fora, em AuditOPA e Rego para o resto
Seção intitulada “OPA e Rego para o resto”Quando a política precisa valer para Terraform, para o pipeline ou para uma API própria, OPA com Rego é a escolha — a mesma engine avalia qualquer JSON.
package terraform.s3
# Nenhum bucket novo pode ser público.deny contains msg if { recurso := input.resource_changes[_] recurso.type == "aws_s3_bucket_public_access_block" recurso.change.after.block_public_acls == false msg := sprintf("bucket %s permite ACL pública", [recurso.address])}terraform plan -out=plano.binterraform show -json plano.bin > plano.jsonconftest test plano.json --policy politicas/ # falha o PR com a mensagem acimaRego tem curva de aprendizado real. Comece por poucas regras de alto valor e escreva teste para cada política — política errada bloqueia entrega legítima e queima a confiança na prática inteira.
test_bucket_publico_e_negado if { count(deny) == 1 with input as {"resource_changes": [...]}}Auditoria antes de bloqueio
Seção intitulada “Auditoria antes de bloqueio”A sequência que funciona, sempre nesta ordem:
- Escreva a regra e rode em modo auditoria, sem bloquear nada.
- Meça quantos recursos existentes violam. Quase sempre é mais do que se imagina.
- Corrija o acervo, ou registre exceção com dono e prazo.
- Bloqueie para recursos novos primeiro.
- Só então bloqueie para tudo.
Ligar Enforce no primeiro dia derruba deploy legítimo, gera um incidente e faz a política
ser desativada “temporariamente” — estado em que ela costuma ficar para sempre.
Exceções com prazo e dono
Seção intitulada “Exceções com prazo e dono”Toda política precisa de uma porta de saída documentada, ou as pessoas vão contornar por fora:
apiVersion: kyverno.io/v2kind: PolicyExceptionmetadata: { name: legado-pagamentos, namespace: pagamentos }spec: exceptions: - policyName: exigir-limites-e-nao-root ruleNames: [sem-root] match: { any: [{ resources: { namespaces: [pagamentos], names: [legado-*] } }] } # Registre no PR: dono @carla, motivo (imagem legada), revisão em 2026-12-01Exceção sem prazo é a política revogada em silêncio. Revise a lista por trimestre — a lista encolhendo é a melhor métrica de que a prática está funcionando.
Mensagens que ensinam
Seção intitulada “Mensagens que ensinam”A mensagem de erro é a documentação que a pessoa realmente lê. Diga o que está errado, por que a regra existe e como corrigir, com link para o guia interno. “Policy violation: require-non-root” custa quinze minutos de alguém; a mesma regra com uma frase útil custa zero.
Próximo passo: aplique essas regras à superfície de host, container e cluster em Hardening.