DevOps & CI/CD

Compliance como Código: OPA, Conftest e Policy Enforcement em Kubernetes na Prática

12 min de leitura

Compliance como Código: OPA, Conftest e Policy Enforcement em Kubernetes na Prática

O Que é Compliance como Código Compliance como Código é um paradigma que transforma políticas e padrões de conformidade em código executável, permitindo que sistemas sejam validados automaticamente contra regras de negócio, segurança e governança. Em vez de manuais em PDF ou checklists manuais, você define suas políticas em linguagens de programação específicas e as aplica de forma contínua no seu pipeline de infraestrutura. No contexto de Kubernetes, isso significa garantir que seus manifestos YAML, configurações de rede, permissões RBAC e deployments estejam sempre em conformidade com os padrões corporativos antes mesmo de serem deployados. Essa abordagem reduz riscos de segurança, evita configurações incorretas e torna a auditoria muito mais simples, já que tudo fica rastreável e versionado no seu repositório Git. OPA (Open Policy Agent): Fundamentos e Arquitetura OPA é um mecanismo de decisão de políticas agnóstico de domínio desenvolvido pela CNCF. Ele usa uma linguagem declarativa chamada Rego para expressar políticas complexas de uma forma legível e testável.

<h2>O Que é Compliance como Código</h2>

<p>Compliance como Código é um paradigma que transforma políticas e padrões de conformidade em código executável, permitindo que sistemas sejam validados automaticamente contra regras de negócio, segurança e governança. Em vez de manuais em PDF ou checklists manuais, você define suas políticas em linguagens de programação específicas e as aplica de forma contínua no seu pipeline de infraestrutura.</p>

<p>No contexto de Kubernetes, isso significa garantir que seus manifestos YAML, configurações de rede, permissões RBAC e deployments estejam sempre em conformidade com os padrões corporativos antes mesmo de serem deployados. Essa abordagem reduz riscos de segurança, evita configurações incorretas e torna a auditoria muito mais simples, já que tudo fica rastreável e versionado no seu repositório Git.</p>

<h2>OPA (Open Policy Agent): Fundamentos e Arquitetura</h2>

<p>OPA é um mecanismo de decisão de políticas agnóstico de domínio desenvolvido pela CNCF. Ele usa uma linguagem declarativa chamada Rego para expressar políticas complexas de uma forma legível e testável. OPA funciona como um servidor que recebe dados em JSON, avalia-os contra suas políticas e retorna decisões estruturadas.</p>

<h3>Como OPA Funciona</h3>

<p>OPA recebe uma requisição contendo um JSON com o contexto que deve ser validado. Você define regras em Rego que analisam esse JSON e produzem uma decisão booleana ou estruturada. A força do OPA está na sua capacidade de trabalhar com qualquer tipo de dado: configurações Kubernetes, requisições HTTP, eventos de auditoria ou até artefatos de container.</p>

<p>Um exemplo simples de política em Rego que garante que todo Pod tenha um <code>securityContext</code> definido:</p>

<pre><code class="language-rego">package kubernetes.admission

deny[msg] {

input.request.kind.kind == &quot;Pod&quot;

not input.request.object.spec.securityContext

msg := &quot;Pods devem ter securityContext definido&quot;

}</code></pre>

<p>Neste código, a regra <code>deny</code> é ativada quando o objeto sendo avaliado é um Pod e ele não possui <code>securityContext</code>. Se a condição for verdadeira, a política retorna uma mensagem de negação.</p>

<h3>Instalando e Configurando OPA</h3>

<p>Para instalar OPA em seu ambiente local, você pode usar o gerenciador de pacotes ou baixar o binário diretamente:</p>

<pre><code class="language-bash"># macOS usando Homebrew

brew install opa

Linux - fazer download do binário

curl -L -o opa https://openpolicyagent.org/downloads/latest/opa_linux_x86_64

chmod +x opa

sudo mv opa /usr/local/bin/</code></pre>

<p>Para testar uma política rapidamente, você pode usar o REPL do OPA:</p>

<pre><code class="language-bash">opa run --server</code></pre>

<p>Isso inicia um servidor OPA na porta 8181. Você pode então fazer requisições POST para <code>/v1/data/&lt;seu-pacote&gt;/&lt;sua-regra&gt;</code> com um JSON contendo seus dados.</p>

<h3>Exemplo Prático: Política de Imagens</h3>

<p>Uma política comum é garantir que todas as imagens de container tenham tags explícitas e venham de registries autorizados:</p>

<pre><code class="language-rego">package kubernetes.admission

import data.lib.utils

deny[msg] {

input.request.kind.kind == &quot;Pod&quot;

container := input.request.object.spec.containers[_]

Verifica se a imagem possui tag

not contains(container.image, &quot;:&quot;)

msg := sprintf(&quot;Container %v deve ter tag explícita (não use &#039;latest&#039;)&quot;, [container.name])

}

deny[msg] {

input.request.kind.kind == &quot;Pod&quot;

container := input.request.object.spec.containers[_]

Verifica registries autorizados

allowed_registries := [&quot;docker.io&quot;, &quot;gcr.io&quot;, &quot;registry.empresa.com&quot;]

registry := split(container.image, &quot;/&quot;)[0]

not utils.contains_array(registry, allowed_registries)

msg := sprintf(&quot;Registry %v não é autorizado&quot;, [registry])

}</code></pre>

<h2>Conftest: Integrando OPA com Seu Pipeline</h2>

<p>Conftest é uma ferramenta de linha de comando que simplifica o teste de configurações contra políticas OPA. Ele recebe arquivos YAML, JSON, Terraform, Dockerfile e outros formatos, valida-os contra suas regras Rego e retorna os resultados de forma clara. Conftest é perfeito para executar validações em seu CI/CD antes que qualquer mudança chegue ao Kubernetes.</p>

<h3>Instalando Conftest</h3>

<pre><code class="language-bash"># macOS

brew install conftest

Linux usando curl

curl -JLO https://github.com/open-policy-agent/conftest/releases/download/v0.46.0/conftest_0.46.0_Linux_x86_64.tar.gz

tar xf conftest_0.46.0_Linux_x86_64.tar.gz

sudo mv conftest /usr/local/bin/</code></pre>

<h3>Estrutura de Projeto com Conftest</h3>

<p>Uma estrutura típica para organizar suas políticas:</p>

<pre><code>projeto-kubernetes/

├── policies/

│ ├── security/

│ │ ├── pod_security.rego

│ │ ├── network_policy.rego

│ │ └── rbac.rego

│ ├── compliance/

│ │ ├── labels_obrigatorios.rego

│ │ └── resource_limits.rego

│ └── utils.rego

├── manifests/

│ ├── deployment.yaml

│ ├── service.yaml

│ └── ingress.yaml

└── tests/

└── policies_test.rego</code></pre>

<h3>Exemplo: Política de Labels Obrigatórios</h3>

<p>Crie o arquivo <code>policies/compliance/labels_obrigatorios.rego</code>:</p>

<pre><code class="language-rego">package main

Labels obrigatórios em todos os recursos

required_labels := [&quot;app&quot;, &quot;version&quot;, &quot;owner&quot;]

deny[msg] {

Verifica todos os tipos de recursos

resource_type := input.kind

resource_type != &quot;Namespace&quot; # Namespaces têm suas próprias regras

Obtém os labels do metadata

labels := object.get(input.metadata, &quot;labels&quot;, {})

Verifica se cada label obrigatório existe

missing := [label |

label := required_labels[_]

not labels[label]

]

count(missing) &gt; 0

msg := sprintf(

&quot;Resource %v/%v está faltando labels: %v&quot;,

[input.kind, input.metadata.name, missing]

)

}</code></pre>

<p>Agora crie um manifesto para testar:</p>

<pre><code class="language-yaml"># manifests/deployment.yaml

apiVersion: apps/v1

kind: Deployment

metadata:

name: minha-app

labels:

app: minha-app

version: &quot;1.0&quot;

owner: devops-team

spec:

replicas: 3

selector:

matchLabels:

app: minha-app

template:

metadata:

labels:

app: minha-app

version: &quot;1.0&quot;

owner: devops-team

spec:

containers:

  • name: app

image: myapp:1.2.3

resources:

requests:

memory: &quot;64Mi&quot;

cpu: &quot;100m&quot;

limits:

memory: &quot;128Mi&quot;

cpu: &quot;200m&quot;</code></pre>

<p>Execute a validação:</p>

<pre><code class="language-bash">conftest test manifests/deployment.yaml -p policies/</code></pre>

<p>Se algum label obrigatório estivesse faltando, Conftest retornaria um erro claro indicando exatamente qual label está ausente e em qual recurso.</p>

<h3>Integrando Conftest no Pipeline GitHub Actions</h3>

<pre><code class="language-yaml">name: Validate Kubernetes Manifests

on:

pull_request:

paths:

  • &#039;manifests/**&#039;
  • &#039;policies/**&#039;

jobs:

conftest:

runs-on: ubuntu-latest

steps:

  • uses: actions/checkout@v3
  • uses: instrumenta/conftest-action@master

with:

files: manifests/

policy: policies/

options: -o json</code></pre>

<p>Este workflow executa Conftest automaticamente toda vez que alguém abre um PR com mudanças em manifestos ou políticas, garantindo conformidade antes do merge.</p>

<h2>Policy Enforcement em Kubernetes: Admission Controllers</h2>

<p>Enquanto Conftest valida manifestos em tempo de build, você também precisa enforçar políticas em tempo de runtime. Kubernetes oferece dois mecanismos: Validating Admission Webhooks e Mutating Admission Webhooks. OPA integra-se perfeitamente nesse ecossistema através do Gatekeeper, um controlador específico para Kubernetes que executa políticas OPA.</p>

<h3>O Que é Gatekeeper</h3>

<p>Gatekeeper é um Kubernetes Admission Controller que intercepta requisições para criar ou modificar recursos e valida-as contra suas políticas OPA antes de permitir que a operação prossiga. Se uma política é violada, a requisição é rejeitada e o usuário recebe uma mensagem de erro clara.</p>

<h3>Instalando Gatekeeper</h3>

<pre><code class="language-bash"># Adicione o repositório Helm

helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts

Instale o Gatekeeper

helm install gatekeeper/gatekeeper \

--namespace gatekeeper-system \

--create-namespace \

--set enableExternalData=true \

--set enableGeneratorResourceExpansion=true</code></pre>

<h3>Exemplo: Implementando uma Restrição de CPU e Memória</h3>

<p>No Gatekeeper, você define ConstraintTemplates (templates de restrição) e depois cria instâncias delas (Constraints). A ConstraintTemplate define a lógica em Rego, e a Constraint especifica os parâmetros e objetivos.</p>

<p>Crie um arquivo <code>constraint-template.yaml</code>:</p>

<pre><code class="language-yaml">apiVersion: templates.gatekeeper.sh/v1

kind: ConstraintTemplate

metadata:

name: k8srequiredresources

spec:

crd:

spec:

names:

kind: K8sRequiredResources

validation:

openAPIV3Schema:

properties:

exemptNamespaces:

type: array

items:

type: string

targets:

  • target: admission.k8s.gatekeeper.sh

rego: |

package k8srequiredresources

violation[{&quot;msg&quot;: msg}] {

container := input.review.object.spec.containers[_]

not container.resources.requests

msg := sprintf(&quot;Container %v deve ter requests definidos&quot;, [container.name])

}

violation[{&quot;msg&quot;: msg}] {

container := input.review.object.spec.containers[_]

not container.resources.limits

msg := sprintf(&quot;Container %v deve ter limits definidos&quot;, [container.name])

}</code></pre>

<p>Agora crie a Constraint que aplica essa restrição:</p>

<pre><code class="language-yaml">apiVersion: constraints.gatekeeper.sh/v1beta1

kind: K8sRequiredResources

metadata:

name: require-resources-all-pods

spec:

match:

kinds:

  • apiGroups: [&quot;&quot;]

kinds: [&quot;Pod&quot;]

excludedNamespaces: [&quot;kube-system&quot;, &quot;kube-public&quot;]</code></pre>

<p>Quando você tentar criar um Pod sem resources definidos, Gatekeeper o rejeitará automaticamente:</p>

<pre><code class="language-bash">$ kubectl apply -f pod-sem-resources.yaml

Error from server ([denied by require-resources-all-pods]

Container nginx deve ter requests definidos):

error when creating &quot;pod-sem-resources.yaml&quot;: admission webhook

&quot;validation.gatekeeper.sh&quot; denied the request</code></pre>

<h3>Auditoria sem Rejeição</h3>

<p>Às vezes você quer monitorar violações sem bloquear deployments imediatamente. Configure o Gatekeeper em modo auditoria:</p>

<pre><code class="language-yaml">apiVersion: constraints.gatekeeper.sh/v1beta1

kind: K8sRequiredResources

metadata:

name: require-resources-all-pods

spec:

enforcementAction: audit # ao invés de &quot;deny&quot;

match:

kinds:

  • apiGroups: [&quot;&quot;]

kinds: [&quot;Pod&quot;]</code></pre>

<p>Com <code>enforcementAction: audit</code>, violações são registradas mas não bloqueiam operações. Isso é útil para um período de transição antes de ativar enforcement total.</p>

<h2>Conclusão</h2>

<p>Compliance como Código transforma governança de infraestrutura de um processo manual e propenso a erros em uma prática automatizada e auditável. Os três aprendizados principais são: (1) <strong>OPA e Rego</strong> fornecem a camada de decisão declarativa, permitindo expressar políticas complexas em código legível e testável; (2) <strong>Conftest</strong> integra validação de políticas no seu pipeline de CI/CD, capturando problemas antes do deployment; (3) <strong>Gatekeeper</strong> enforce políticas em runtime no Kubernetes, servindo como última linha de defesa contra configurações não-conformes.</p>

<p>Implementar essa stack não é apenas sobre segurança — é sobre confiabilidade. Quando suas políticas estão codificadas, versionadas e testadas, você elimina configurações manuais inconsistentes e cria um ambiente onde conformidade é a regra, não a exceção.</p>

<h2>Referências</h2>

<ol>

<li><a href="https://www.openpolicyagent.org/docs/latest/" target="_blank" rel="noopener noreferrer">Open Policy Agent Official Documentation</a></li>

<li><a href="https://github.com/open-policy-agent/conftest" target="_blank" rel="noopener noreferrer">Conftest GitHub Repository</a></li>

<li><a href="https://open-policy-agent.org/docs/latest/kubernetes-introduction/" target="_blank" rel="noopener noreferrer">Gatekeeper: Policy Controller for Kubernetes</a></li>

<li><a href="https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/" target="_blank" rel="noopener noreferrer">Kubernetes Admission Controllers Documentation</a></li>

<li><a href="https://www.cncf.io/blog/2021/12/01/policy-as-code-the-api-gateway-use-case/" target="_blank" rel="noopener noreferrer">CNCF Policy as Code Whitepaper</a></li>

</ol>

<p>&lt;!-- FIM --&gt;</p>

Comentários

Mais em DevOps & CI/CD

Feature Flags: como realizar deploys mais seguros e confiáveis
Feature Flags: como realizar deploys mais seguros e confiáveis

A gestão de mudanças no código-fonte de um sistema é uma tarefa constante e d...

O que Todo Dev Deve Saber sobre AWS Avançado: EKS, ECS, Lambda e RDS em Ambientes Reais
O que Todo Dev Deve Saber sobre AWS Avançado: EKS, ECS, Lambda e RDS em Ambientes Reais

Arquitetura Moderna na AWS: Da Orquestração de Contêineres ao Serverless A co...

AWS Fundamentos para DevOps: IAM, VPC, EC2 e S3 na Prática: Do Básico ao Avançado
AWS Fundamentos para DevOps: IAM, VPC, EC2 e S3 na Prática: Do Básico ao Avançado

IAM: Controle de Acesso e Identidade na AWS O Identity and Access Management...