Home Comunidade Eventos YouTube Networks Desafios // produtos Academy News CTI | CVE Contato

04 - Testes Automatizados e CI-CD para Detecções

video explicativo
Video explicativoEspaco reservado para o video desta anotação — adicione video: https://youtu.be/... no frontmatter da nota.

Testes Automatizados e CI-CD para Detecções

Nota de fechamento da pasta de Detection-as-Code do capítulo 18, sobre Detection Engineering e Automação.
Define a pirâmide de testes de detecção e a pipeline de CI/CD que valida e publica regras por estágio, com exemplo completo de workflow.
Dialoga com os repositórios de regras da nota anterior, com a conversão de Sigma e o deploy automatizado da pasta de Pipeline de Detecção.

1. Contexto e Posicionamento na Biblioteca

As notas anteriores organizaram o ciclo de vida das detecções e o repositório que as versiona, e esta nota descreve o componente que dá confiabilidade ao processo: os testes automatizados e a pipeline de integração e entrega contínua. Sem testes, a revisão por pares julga aparência, e sem pipeline, o deploy volta a ser manual e o console reconquista seu papel de caminho real de mudança. Juntas, as duas práticas transformam o fluxo de regras em uma esteira com portões objetivos, onde a qualidade é verificada por máquina e o humano decide o que a máquina não decide.

A nota segue a lógica da pirâmide de testes da engenharia de software, adaptada à natureza das detecções, e apresenta um exemplo completo de pipeline em GitHub Actions que pode ser adaptado pelo leitor. A pasta de Pipeline de Detecção assume o conteúdo desta nota como base: a conversão de Sigma roda dentro de pipelines como a descrita aqui, e o deploy automatizado é o estágio final dessa mesma esteira.

2. A Pirâmide de Testes de Detecção

Os testes de detecção organizam-se em quatro camadas de custo e valor crescentes, e a composição equilibrada de todas as camadas é o que protege o catálogo. A tabela abaixo define cada camada com o objetivo, o insumo típico e a velocidade de execução, critério que determina onde cada teste roda, se em pull request, em merge ou em cadência programada.

Camada Objetivo Insumo típico Velocidade
Teste unitário de arquivo Valida schema, metadados obrigatórios e lint Arquivo YAML ou TOML da regra Segundos, roda em todo PR
Teste de lógica Confirma que a consulta expressa a lógica do desenho Consulta compilada e eventos sintéticos Segundos a minutos, em todo PR
Teste de integração Confirma que a regra compila e dispara no motor real Instância do SIEM ou EDR de teste Minutos, em merge na principal
Teste de regressão Confirma que mudanças não degradam comportamento anterior Corpus histórico rotulado Minutos a horas, em merge e diário

O teste unitário de arquivo é a base da pirâmide e o mais barato de manter, verificando sintaxe do formato, campos obrigatórios, unicidade de identificadores e padrões de nomenclatura. O teste de lógica executa a consulta contra eventos sintéticos preparados para casar e para não casar com a detecção, um verdadeiro positivo obrigatório e falsos positivos planejados no desenho. O teste de integração sobe o motor real, Elastic, Splunk ou Wazuh em ambiente efêmero de CI, compila e executa a regra contra os dados injetados, pegando incompatibilidades de dialeto que a compilação isolada não pega. O teste de regressão roda o catálogo inteiro contra o corpus histórico sempre que algo muda, e é ele que responde a pergunta da revisão: esta mudança quebrou alguma outra regra?

A disciplina essencial da pirâmide é o rótulo dos dados: cada evento sintético e cada amostra histórica carrega a expectativa, alerta esperado ou não alerta, e a pipeline compara o comportamento do motor com a expectativa declarada. Sem essa comparação declarativa, o teste degrada a log de execução sem veredito, e log que ninguém avalia não é teste, é telemetria.

3. Dados Sintéticos e Representatividade do Ambiente de Teste

O dado sintético é a matéria-prima dos testes, e sua qualidade determina o valor de toda a pirâmide. Existem três modos de obtê-lo: geradores que emitem eventos construídos campo a campo, frameworks de emulação de adversário como o Atomic Red Team, que executam técnicas ATT&CK reais em ambiente controlado e capturam a telemetria resultante, e amostras históricas reais extraídas do próprio ambiente, com dados sensíveis mascarados quando necessário.

A representatividade é o critério central de um ambiente de teste útil, e tem duas dimensões que o time precisa equilibrar. A dimensão de fidelidade exige que os eventos sintéticos tenham os mesmos nomes de campo, tipos e valores que a produção produz, porque uma regra validada contra um campo do tipo errado quebra silenciosamente em produção. A dimensão de volume e ruído exige que o corpus inclua os padrões benignos do ambiente real, como varreduras de inventário, jobs de backup e ferramentas de administração, porque é contra esse ruído que a regra precisa manter precisão.

  • Manter corpus versionado no repositório: os eventos de teste vivem junto às regras, em formato JSON ou NDJSON, com entrada por evento e expectativa explícita, e a mudança de uma regra que altera a expectativa de um evento precisa justificar a alteração do corpus no mesmo pull request.
  • Capturar telemetria de emulação no laboratório: executar o caso de teste do Atomic Red Team, por exemplo o caso T1059.001 de PowerShell com cradle, em uma VM instrumentada com Sysmon produz o evento real que a regra encontrará, e esse evento capturado alimenta o teste de integração de forma permanente.
  • Mascarar dados sensíveis nas amostras históricas: nomes de usuários, endereços e hostnames reais são substituídos de forma reversível antes de o corpus entrar no repositório, preservando estrutura e mantendo conformidade com a política de dados da organização.
  • Revalidar o corpus com mudanças de schema: atualizações do agente de coleta ou do produto mudam nomes de campos, e a cadência trimestral de comparação entre corpus e schema de produção evita testes verdes contra uma realidade desatualizada.

O ambiente de teste ideal não é uma cópia de produção, é uma amostra de produção: um conjunto de indexadores ou uma instância reduzida recebendo o corpus rotulado, com versões de plataforma e configurações de coleta equivalentes às de produção. A cópia integral de produção traz custo e risco de dados que raramente se justificam, e a amostra traz a fidelidade necessária aos testes da pipeline.

4. Pipeline de CI/CD para Detecções, Estágio por Estágio

A pipeline de detecções encadeia os estágios de validação e publicação, e cada estágio é um portão: o falhar de qualquer checagem interrompe o fluxo e impede o merge ou o deploy. A sequência típica em pull request é lint, validação de schema, compilação e conversão, teste de lógica e relatório de impacto, e a sequência após o merge é teste de integração, deploy por estágio e verificação pós-deploy. O exemplo abaixo mostra um workflow completo de GitHub Actions para um catálogo em Sigma com destino em Elastic e Splunk.

name: detection-pipeline

on:
  pull_request:
    paths:
      - "rules/**"
  push:
    branches: [main]
    paths:
      - "rules/**"

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: yamllint nos arquivos de regra
        run: yamllint -d relaxed rules/
      - name: validacao de schema e checagens Sigma
        run: |
          pip install sigma-cli pysigma
          sigma check rules/sigma/
  test-logic:
    needs: lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: testes de logica com eventos sinteticos
        run: python tests/run_detection_tests.py --corpus tests/synthetic/
      - name: regressao contra corpus historico
        run: python tests/run_regression.py --corpus tests/regression/ --threshold 95
  build:
    needs: test-logic
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: converter Sigma para KQL e SPL
        run: |
          sigma convert -t kusto -p microsoft_sentinel rules/sigma/ -o out/kql/
          sigma convert -t splunk -p splunk rules/sigma/ -o out/spl/
      - uses: actions/upload-artifact@v4
        with:
          name: compiled-rules
          path: out/
  deploy-dev:
    needs: [build, test-integration]
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: dev
    steps:
      - uses: actions/download-artifact@v4
        with: { name: compiled-rules }
      - name: publicar regras no ambiente de desenvolvimento
        run: python tools/push_rules.py --env dev --src out/
  deploy-prod:
    needs: deploy-dev
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/download-artifact@v4
        with: { name: compiled-rules }
      - name: publicar regras em producao
        run: python tools/push_rules.py --env prod --src out/
      - name: verificacao pos-deploy
        run: python tools/verify_rules.py --env prod --expected-manifest manifest.json
  test-integration:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: subir motor de teste e rodar casos
        run: docker compose -f tests/docker/elasticsearch.yml up --exit-code-from runner

O workflow acima ilustra três decisões de desenho que valem destaque. O uso de ambientes do GitHub, com o bloco environment, permite exigir aprovação humana antes do deploy de produção, implementando o estágio de homologação descrito na nota de DDLC. A separação entre jobs de build e deploy garante que o artefato publicado em produção é exatamente o artefato testado, e não uma recompilação. A verificação pós-deploy compara o manifesto esperado com o estado da plataforma e falha o job se algo divergir, fechando o ciclo de garantia dentro da própria pipeline.

5. Métricas de Qualidade da Pipeline

A pipeline é um produto, e medir sua saúde evita que a esteira vire gargalo invisível. As métricas relevantes dividem-se em duas famílias: as de eficiência do fluxo, que medem velocidade, e as de eficácia da barreira, que medem o quanto a pipeline captura de defeitos antes de produção.

Métrica Como medir Alvo indicativo
Lead time de detecção Tempo da abertura do PR ao deploy em produção Menos de 2 dias úteis para regras de nível alto
Taxa de falso verde Defeitos encontrados em produção que os testes deveriam ter pegado Tendendo a zero, com análise por caso
Duração da pipeline de PR Tempo total do ciclo de jobs no pull request Menos de 10 minutos para não travar o fluxo
Taxa de re-trabalho pós-deploy Proporção de deploys seguidos de tuning corretivo imediato Abaixo de 20 por cento das regras novas
Cobertura da pipeline Regras que passam por todas as camadas de teste Cem por cento, exceções registradas
Flakiness de teste Testes que alternam resultado sem mudança de código Abaixo de 1 por cento das execuções

O falso verde é a métrica mais importante da família de eficácia, porque cada defeito que passa pela barreira mina a confiança no processo e convida ao deploy manual de emergência. Cada caso de falso verde gera um teste novo que impede a reincidência: o incidente vira corpus, e a barreira aprende com a falha, que é exatamente o comportamento que se espera de um processo de engenharia maduro.

6. Erros Comuns e Pontos de Atenção

  • Pipeline que só roda lint: a esteira que valida formato sem testar comportamento dá falsa sensação de qualidade, porque schema correto não implica detecção correta. Pelo menos uma camada de teste de lógica é o mínimo aceitável.
  • Corpus congelado há anos: dados de teste que não acompanham a evolução da telemetria passam a validar contra uma realidade inexistente, e a cadência de revisão do corpus é tão importante quanto a cadência das regras.
  • Teste de integração frágil por dependência externa: subir motor de teste que depende de serviço externo instável torna a pipeline intermitente, e a equipe aprende a ignorar falhas, queimando a confiança na barreira. Instâncias efêmeras em contêiner resolvem a maior parte dos casos.
  • Deploy sem verificação pós-publicação: publicar e assumir sucesso esconde falhas de API, rate limit e regras rejeitadas silenciosamente pela plataforma, e a comparação de manifesto pós-deploy custa minutos e evita semanas de lacuna invisível.
  • Threshold de regressão arbitrário: exigir 100 por cento de paridade histórica trava evoluções legítimas de schema, enquanto thresholds frouxos deixam passar degradação. O número é negociado por classe de regra e revisado com dados.
  • Testar apenas regras novas: mudanças em regras antigas e em configurações de plataforma afetam o catálogo inteiro, e a execução de regressão completa em merges de manutenção cobre exatamente essa lacuna.

7. Integração com o Restante da Biblioteca

Na pasta de Pipeline de Detecção, a nota de conversão de Sigma executa o estágio de build descrito aqui, com aprofundamento nos backends e nas limitações da tradução entre dialetos, e a nota de deploy automatizado expande o estágio final com Terraform, estados e estratégias de rollback. A nota de simulação de alertas fornece a camada que complementa esta pirâmide: os testes aqui descritos comprovam a lógica e a publicação, e a simulação comprova o circuito completo, do evento injetado no agente até o alerta criado na plataforma.

No restante da biblioteca, o controle SIM.5 sobre medição de cobertura de detecção consome os resultados desta pipeline como evidência de comportamento testado, o controle SIM.4 sobre teste de detecção de IOCs e IOAs fornece os casos de emulação que abastecem o corpus sintético, e a nota de KPIs para CTI do capítulo 11 incorpora as métricas de lead time e falso verde como indicadores do programa. O controle DAT.5 sobre qualidade e retenção de dados define as condições que o corpus precisa manter para continuar representativo, fechando o vínculo entre engenharia de detecção e engenharia de dados.