Rodar varredura em produção manualmente todo dia não escala. Guia passo a passo de como integrar varredura contínua no pipeline CI/CD, bloquear deploy quando encontrar crítico e não incomodar dev com falso positivo.
Varredura semanal manual funciona pra time pequeno até virar rotina esquecida. Depois disso, precisa entrar no pipeline. Este guia mostra como integrar sem quebrar o fluxo do time.
Modelo mental
Duas execuções distintas:
- Preflight: roda no ambiente de staging antes de merge para main. Se encontra crítica nova, PR não pode fazer merge.
- Post-deploy: roda em produção depois de cada deploy. Se encontra crítica, alerta imediato + rollback opcional.
GitHub Actions — Workflow básico
.github/workflows/security-scan.yml:
name: Security Scan
on:
pull_request:
branches: [main]
push:
branches: [main]
jobs:
varredura:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run varredura
env:
VARREDURA_TOKEN: ${{ secrets.VARREDURA_TOKEN }}
TARGET_URL: ${{ github.event_name == 'pull_request' && 'https://staging.exemplo.com' || 'https://exemplo.com' }}
run: |
curl -X POST https://varredura.com.br/api/scan \
-H "Authorization: Bearer $VARREDURA_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"url\":\"$TARGET_URL\",\"severity_threshold\":\"high\"}" \
--fail-with-body
severity_threshold: high = falha o job só em findings altas+.
GitLab CI — Equivalente
security-scan:
stage: test
script:
- |
curl -X POST https://varredura.com.br/api/scan \
-H "Authorization: Bearer $VARREDURA_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"url\":\"$CI_ENVIRONMENT_URL\",\"severity_threshold\":\"high\"}" \
--fail-with-body
only:
- merge_requests
- main
Como evitar bloquear PR por falso positivo
- Baseline: primeira execução é referência. Só bloqueia se surgir NOVA finding.
- Threshold: só crítica bloqueia. Média entra em relatório.
- Waiver: finding pode ser marcada "aceita" com justificativa (arquivo
.varredura.yamlno repo).
Alertas em Slack/Discord
Adiciona no workflow:
- name: Notify on findings
if: failure()
run: |
curl -X POST $SLACK_WEBHOOK \
-H 'Content-Type: application/json' \
-d "{\"text\":\"🚨 Varredura encontrou crítica em $TARGET_URL. Ver: https://varredura.com.br/relatorio/$SCAN_ID\"}"
Modo "pre-flight" vs "post-deploy"
- Pre-flight (staging): bloqueia merge. Erro claro pro dev. Tem que ser rápido (< 3min).
- Post-deploy (prod): informa, não bloqueia. Rollback é decisão humana (a menos que você seja maduro pra rollback automático).
Rollback automático — quando faz sentido
Não faz sentido no ano 1. Requer:
- Deploy blue-green ou canary.
- Métrica confiável de "produção OK".
- Runbook testado.
Se você não tem, não coloque. Um rollback errado é pior do que uma finding não corrigida na hora.
Falso positivo — como o time reage
Regra 1: finding nova não é falso positivo até prova em contrário.
Regra 2: se time gasta > 2h investigando uma finding e conclui falso positivo, marca no .varredura.yaml com justificativa e link do investigation.
Regra 3: falso positivo rate > 15% = trocar ferramenta. Não é normal.
Métricas de saúde
- Tempo médio de scan: 60-120s ideal.
- Findings críticas: 0 em produção, sempre.
- Findings médias: tendência descendente semana a semana.
- Waivers ativos: revisar mensalmente.
TL;DR
- 2 execuções: preflight staging + post-deploy prod.
- Threshold "high" para bloquear.
- Baseline evita ruído.
- Waiver com justificativa.
- Slack alert em failure.
Integração pronta em 30min. Ver documentação.
Sua app em produção passa por essa análise?
Rode uma varredura autônoma em ~60 segundos. Sem cadastro.