Adicionar scanners de SAST, dependências, segredos e infraestrutura a um pipeline leva uma tarde. O problema começa na semana seguinte, quando cada pull request mostra duzentos findings, a maioria com anos, e o build falha por algo em que o autor não mexeu. Os programadores aprendem a passar os comentários à frente, depois a voltar a correr até ficar verde, e depois a pedir que a verificação passe a opcional.
A nossa posição é simples: um scanner ignorado dá menos segurança do que um scanner mais pequeno que é lido. O objetivo não é o máximo de achados. São os achados certos, à frente da pessoa certa, no momento em que os pode corrigir.
Porque é que os programas de análise se afogam
Três padrões aparecem uma e outra vez:
- Histórico em cada PR. Findings antigos são reportados contra trabalho novo, por isso o autor paga por dívida que não criou.
- Tudo bloqueia. Findings médios e baixos fazem falhar o build, por isso o gate não significa nada e acaba contornado.
- Duplicados e código inalcançável. A mesma biblioteca vulnerável é reportada por manifest, por imagem e por serviço, muitas vezes em caminhos que nunca correm.
Nenhum destes é um problema de ferramentas. São decisões de política que nunca foram tomadas.
Ponha os achados onde a correção acontece
Antes de afinar qualquer scanner, decida onde vai parar o seu output. Um achado em código alterado deve ser um comentário inline no pull request, junto à linha, escrito para que o autor possa agir sem abrir outra ferramenta. Um achado em código antigo pertence ao backlog da equipa responsável, agrupado por serviço. Um achado sem dono não pertence a lado nenhum até alguém o assumir, o que é um sinal para corrigir a ownership e não para abrir mais tickets.
Elimine duplicados antes de qualquer coisa chegar a uma pessoa. Uma biblioteca vulnerável usada por dez serviços é uma decisão sobre uma atualização, não dez tickets. Ao ordenar o backlog, dê prioridade à alcançabilidade e à existência de correção sobre a severidade bruta, e diga-o no comentário, para que os programadores percebam porque um item está onde está.
Baseline do backlog, e depois assuma-o
Tire um snapshot do que existe hoje e deixe de o reportar nos pull requests. Esse backlog não desaparece: passa a ser uma lista com um dono e um calendário, tratada como qualquer outra dívida técnica. O código novo, entretanto, é avaliado apenas pelo que introduz.
# Gitleaks: record today's findings, then report only new ones
gitleaks git --report-path gitleaks-baseline.json
gitleaks git --baseline-path gitleaks-baseline.json
A baseline é uma linha de partida, não uma amnistia. Reveja-a, faça a triage do pior no primeiro mês e reduza-a a cada trimestre.
Analise o diff, varra o resto
Nos pull requests, reporte achados apenas no código alterado. A maioria dos scanners open source suporta isto diretamente:
# Semgrep: only findings not present on main
semgrep scan --config auto --baseline-commit origin/main --error
# Gitleaks: only commits in this branch
gitleaks git --log-opts="origin/main..HEAD"
As análises ao repositório completo continuam a correr, à noite ou semanalmente, e alimentam o backlog em vez de um pull request. Essa separação importa. O pull request é uma conversa com um programador sobre a sua alteração. A análise agendada é uma conversa com uma equipa sobre o seu serviço.
Bloquear num conjunto restrito
Acorde, por escrito, o que bloqueia um merge. Mantenha a lista curta o suficiente para que cada bloqueio justifique parar:
| Scanner | Bloqueia o merge | Só relatórios |
|---|---|---|
| Secrets | Qualquer secret novo verificado ou de alta confiança | Fixtures de teste, correspondências de baixa entropia |
| SAST | Regras de alta confiança para injeção, autenticação ou criptografia | Regras de estilo e de baixa confiança |
| SCA | Crítico ou alto, com correção disponível | Sem correção, baixo, só em dev |
| IaC | Storage público, portas de administração abertas, IAM com wildcards | Verificações de tagging e higiene |
trivy fs --scanners vuln --severity HIGH,CRITICAL --ignore-unfixed --exit-code 1 .
trivy config --severity HIGH,CRITICAL --exit-code 1 ./infra
Cada supressão precisa de uma razão e de uma data de expiração no código, para poder ser revista. Uma supressão sem razão é apenas um bypass mais discreto.
O que faríamos
- Ponha todos os scanners em modo report-only durante duas semanas e meça o volume por pull request.
- Escreva a tabela de pontos de controlo acima para a sua organização e acorde-a com os engineering leads, não só com a segurança.
- Faça uma baseline dos achados existentes, atribua o backlog de cada repositório à equipa responsável e defina uma meta trimestral.
- Passe as análises de pull requests para diff-only e depois ative o bloqueio para as regras acordadas.
- Reveja mensalmente a taxa de falsos positivos e remova as regras sobre as quais ninguém age.
A medida de sucesso não é o número de achados. É se os programadores leem o comentário, corrigem o problema e fazem merge, sem pedir à segurança para o fazer desaparecer.