Ir para o conteúdo

13. IA (Inteligência Artificial)

Versão de referência: v0.8.3 — revisão de 2026-07-04.

Este documento descreve, de forma fiel ao código (as-is), o uso de Inteligência Artificial no Quorum (quorum-sec-scan, v0.8.3). O resumo em uma frase: o núcleo do Quorum não usa IA e é 100% determinístico; existe uma camada consultiva opcional (--advice, off por padrão) que pode consultar um modelo local ou remoto, e que nunca toca o núcleo.

Núcleo (sempre, sem IA). Não há LLM/ML no caminho que decide findings: a orquestração dos 12 scanners OSS, a normalização canônica, a correlação por correlationKey, o crosswalk (crosswalk/*.yaml) e o score de consenso são determinísticos e baseados em regras. O Fingerprint = sha256(correlationKey) e a decisão de pass/fail do gate são reproduzíveis e independem de qualquer modelo. A única dependência externa que poderia ser confundida com "inteligência" é o OSV.dev, uma API HTTP determinística e não-ML (ver §2).

Retrieval OWASP determinístico (Fase 2, sob --advice, sem IA). Sob --advice, além dos templates da Fase 0, o Quorum faz RAG sobre um corpus OWASP versionado e pinado por digest (knowledge/owasp/corpus.yaml, pacote internal/rag) e anexa as passagens mais relevantes como referências. O retrieval padrão é léxico (determinístico, air-gapped, sem modelo); há um caminho semântico por embeddings quando o corpus traz vetores (gerados com quorum advise-index) e há um endpoint local — o scan seleciona semântico automaticamente quando o corpus está embedado. Isso não é inferência de LLM — é recuperação sobre um artefato imutável.

Camada consultiva opt-in com LLM (Fase 1/3, off por padrão). Quando — e somente quando — o operador passa --advice --advice-provider=local, o Quorum consulta um modelo local (endpoint OpenAI-compatible, ex.: Ollama) para gerar uma recomendação em linguagem natural e, sob --fix=suggest, um patch verificado (que só é mostrado se sobreviver a um re-scan — verify-the-fix). Essa saída é presentational-only, sempre rotulada "AI-generated, advisory only", e não altera correlationKey/fingerprint/confidence/severidade nem o gate. Sem a flag, o relatório é byte-idêntico ao de um build sem IA. Também existe um provedor remoto (--advice-provider=remote), com guardrails muito mais estritos (ver §4). O design completo e os guardrails estão em 21-proposta-ia; as implicações de risco (o OWASP LLM Top 10 deixa de ser N/A quando a camada é ligada) estão na §4.

Cross-links: DESIGN.md (modelo de dados, matriz de correlação §6, matemática do consenso, alias §7), README.md.


1. Veredito: por que o núcleo é sem IA (e a IA continua opt-in)

O Quorum é uma camada de correlação + consenso sobre scanners de segurança open-source. Na v0.8.3 são 12 scanners orquestrados: Trivy, Grype, Checkov, KICS, Dockle, Kubescape, Polaris, kube-score (K8S_POSTURE), Terrascan, tfsec, Regula (MISCONFIG/IaC) e Conftest (policy-as-code, executa o Rego de ./policy). Todos os adapters ficam em internal/adapter. Ele é CLI/Docker only, projetado para rodar dentro de um pipeline de CI/CD e "gate" um build via exit code. Nesse desenho, determinismo e reprodutibilidade são requisitos de primeira ordem: o mesmo input deve produzir o mesmo Fingerprint = sha256(correlationKey) em qualquer execução, para que o GitHub code scanning / DefectDojo possam deduplicar findings entre runs.

O consenso, que na v0.2.3 se restringia a SCA, agora atua também em MISCONFIG/K8S via crosswalk derivado de output real dos scanners (princípio "false split > false merge") — crosswalk/aws.yaml, crosswalk/azure.yaml, crosswalk/gcp.yaml (hub AVD) e crosswalk/k8s.yaml (hub C-#### do Kubescape). Isso continua sendo casamento por regras determinísticas, não inferência de modelo.

IA generativa é, por natureza, probabilística e não-determinística, o que colidiria diretamente com:

  • o princípio de design "false split > false merge" (na dúvida, mantém findings separados — um merge errado esconde risco);
  • o requisito de fingerprints estáveis entre execuções;
  • a auditabilidade exigida de uma ferramenta de segurança que decide se um build passa ou falha.

Por isso, o núcleo não carrega nenhum modelo, e as partes de IA são estritamente opt-in e off por padrão.

Evidência no código (verificada na v0.8.3):

  • go.mod declara apenas github.com/spf13/cobra e gopkg.in/yaml.v3 como dependências diretas (mais pflag/mousetrap indiretas). Nenhuma biblioteca de ML/LLM/vetorial está vendorada — a camada consultiva opt-in fala com um endpoint OpenAI-compatible externo via net/http e não precisa de runtime de modelo no binário.
  • O caminho determinístico do núcleo (orquestra → normaliza → alias → crosswalk → correlaciona → score → report) não importa código de IA. Todo termo ligado a IA (llm, embedding, rag, advice, advisor, openai) está confinado aos pacotes opt-in internal/advisor, internal/rag, internal/enrich, internal/evals e a fixtures de teste. A palavra "vector" em internal/adapter/testdata/sca_grype_alpine.json e sca_trivy_alpine.json é uma string de CVSS vector (ex.: CVSS:3.1/AV:N/AC:L/...), sem relação com IA.
  • Sem --advice, nenhum código consultivo executa e o relatório é byte-idêntico ao de um build totalmente sem IA. O único cliente de rede do núcleo continua sendo internal/alias/osv.go — um net/http GET contra https://api.osv.dev/v1/vulns/<id> (ver §2).
flowchart LR
  T[target] --> O[orchestrator<br/>fan-out paralelo]
  O --> S["12 scanners OSS<br/>(trivy/grype/checkov/kics/<br/>dockle/kubescape/polaris/<br/>kube-score/terrascan/tfsec/<br/>regula/conftest)"]
  S --> N[normalize<br/>model.Finding]
  N --> A["resolve aliases<br/>(OSV.dev — API HTTP)"]
  A --> X["crosswalk<br/>rule→canonicalControl<br/>(YAML determinístico)"]
  X --> C["correlate<br/>correlationKey determinístico"]
  C --> SC["score<br/>confidence (fórmula)"]
  SC --> R[report<br/>SARIF/JSON/XML + métricas]
  classDef ai fill:#fdd,stroke:#c00;
  classDef det fill:#dfd,stroke:#080;
  class O,S,N,X,C,SC,R det;
  class A det;

Nota: a etapa de "resolve aliases" usa rede (OSV.dev), mas continua determinística e não-ML. Nenhuma caixa do pipeline contém um modelo. O crosswalk é apenas casamento de regras carregadas de YAML versionado. A camada consultiva opt-in (--advice) é um passo separado de apresentação, após a correlação — não está neste caminho de decisão.


2. A única "inteligência" externa: OSV.dev (determinística, não-ML)

A resolução de aliases (internal/alias/) unifica identificadores de vulnerabilidade — por exemplo, o GHSA-… do Grype e o CVE-… do Trivy para o mesmo bug — para que correlacionem em vez de se dividirem (DESIGN §7).

Isto não é IA. É uma cadeia de lookup em três camadas, com preferência determinística por CVE:

flowchart TD
  ID[id de vuln + aliases locais do scanner] --> L1{CVE já presente?}
  L1 -- sim --> OUT[retorna CVE]
  L1 -- não --> L2{cache local hit?<br/>~/.cache/quorum/aliases.json}
  L2 -- sim --> OUT2[retorna valor cacheado]
  L2 -- não --> L3{--offline?}
  L3 -- sim --> DEG[degrada: melhor id local]
  L3 -- não --> OSV["OSV.dev GET /v1/vulns/&lt;id&gt;<br/>HTTP 8s timeout, 2 retries"]
  OSV -- ok --> PICK[preferCVE aliases → grava cache]
  OSV -- erro de rede --> DEG2[degrada graciosamente]

Propriedades relevantes (de internal/alias/resolver.go e osv.go, confirmadas na v0.8.3):

Propriedade Valor Por que importa
Tipo de serviço API HTTP JSON (api.osv.dev/v1/vulns/<id>) Consulta de banco de aliases, não inferência de modelo
Determinismo preferCVE: CVE > GHSA > primeiro não-vazio Mesmo input → mesma saída
ML envolvido Nenhum É lookup em base curada da comunidade
Falha de rede Degradação graciosa (nunca falha o scan) DESIGN §7
Desligar Flag --offline (passa osv=nil) Execução 100% local/air-gapped
Timeout/retries Timeout: 8s, MaxRetries=2, backoff exponencial Robustez de CI
Cache em disco aliases.json com perm 0600 e schemaVersion Reprodutibilidade e higiene

Conclusão: OSV.dev é equivalente a um DNS/whois de vulnerabilidades — dados de referência determinísticos, não um modelo que "raciocina".


3. Itens do template de IA — status item a item

A tabela abaixo cobre cada item esperado em uma seção de IA enterprise e declara o status para o Quorum as-is (v0.8.3). Como a camada consultiva é opt-in e off por padrão, cada item tem dois estados: o build padrão (sem --advice), e o build com --advice ligado.

Item do template Padrão (sem --advice) Com --advice ligado
Modelos de linguagem (LLM) N/A — nenhum LLM no caminho de decisão Modelo local/remoto opt-in, presentational-only (internal/advisor)
Provedor de modelo (OpenAI/Anthropic/etc.) N/A — nenhum cliente de provedor ativo Qualquer endpoint OpenAI-compatible (local, ex.: Ollama) ou uma API remota
Prompts / templates de prompt N/A — não há prompts System prompt fixo; conteúdo de finding passado como UNTRUSTED DATA delimitado (internal/advisor/prompt.go)
RAG (Retrieval-Augmented Generation) N/A — não há geração RAG-as-artifact sobre corpus OWASP pinado por digest (internal/rag), determinístico
Embeddings / busca semântica N/A — correlação por correlationKey determinístico + crosswalk YAML Opcional: cosine top-k sobre vetores do corpus quando embedado via quorum advise-index
Vector database (pgvector/Pinecone/etc.) N/A — sem banco vetorial Continua nenhum: os vetores ficam inline no arquivo de corpus pinado, não num DB vivo
Fine-tuning / treinamento de modelo N/A — não há modelo para treinar N/A — o Quorum não treina nada; apenas consulta um modelo externo
Inferência / serving de modelo N/A — sem runtime de inferência (sem ONNX/TF/PyTorch) Servido fora do binário pelo endpoint do operador; nenhum runtime é vendorado
MCP (Model Context Protocol) N/A — não é cliente/servidor MCP N/A — a camada consultiva fala HTTP OpenAI-compatible, não MCP
Agentes / orquestração agentic N/A — "orchestrator" = fan-out de goroutines para 12 scanners N/A — um request/response por finding; o único loop é o verify-the-fix (um re-scan, não um agente)
Function-calling / tool-use de modelo N/A — não há modelo para invocar ferramentas N/A — completion de texto puro; não há tool-calling
Guardrails de modelo / content moderation N/A — sem saída de modelo Prompt anti prompt-injection, rotulagem advisory-only, cap --advice-max, saída clampada
Avaliação de modelo (evals) Contract tests de adapters validam a qualidade (cobertura no CI) Harness internal/evals mede cobertura de remediação, relevância das referências OWASP e a taxa de verify-the-fix (roda no CI, sem modelo pesado)
Observabilidade de IA (tracing de tokens/custos) N/A — sem chamadas a modelos; telemetria (--metrics, --log-format) é de execução Métricas consultivas: quorum_advice_enriched{kind}, quorum_advice_provider{provider}, quorum_advice_fix{stage} (verified/proposed = taxa de verify-the-fix)
Custos de inferência N/A — OSV.dev é gratuito e determinístico Local: apenas compute on-host. Remoto: o que a API externa cobrar (conta do operador)
Versionamento de modelo / model registry N/A — versionamento é do binário/imagem (GoReleaser/GHCR, atestação SLSA + SBOM) Provider/modelo gravados em cada Advice; o corpus OWASP é pinado por digest e recebe sua própria atestação de proveniência SLSA a cada release
Privacidade de dados enviados a modelos N/A — nada é enviado a um LLM; ao OSV.dev só vai o id de vuln Local: nada sai da máquina. Remoto: só o finding normalizado é enviado, nunca código-fonte, e apenas com consentimento explícito (ver §4)

4. Riscos de IA — aplicabilidade com justificativa

Com a camada consultiva desligada (padrão), não há componente de IA no caminho de execução e a superfície de ataque específica de IA não existe — a tabela abaixo vale integralmente. Quando o operador liga --advice-provider= local, os itens do OWASP LLM Top 10 passam a se aplicar e são mitigados assim: conteúdo de finding é enviado como dado não-confiável delimitado (o system prompt proíbe tratá-lo como instrução — anti prompt-injection); a saída é advisory-only e rotulada, nunca altera o gate (limita insecure output handling/excessive agency); o modelo é local (nenhum código sai da máquina); e todo patch passa pelo verify-the-fix (re-scan) antes de aparecer (mitiga hallucination). O artefato do modelo é uma dependência de supply chain a ser pinada/atestada. Ver 21-proposta-ia §8.

Provedor remoto (Fase 3, --advice-provider=remote). Só aqui dados saem da máquina: os findings normalizados (títulos, caminhos, controles) vão a uma API externa. Por isso é off por padrão e gated em consentimento explícito (--advice-allow-egress + QUORUM_ADVICE_API_KEY), bloqueado por --offline, e recusa --fix (faria upload de código-fonte). Só o finding normalizado é enviado — nunca o código. Sensitive information disclosure é assim limitado a metadados de finding, com consentimento.

Risco de IA (OWASP LLM Top 10 / similares) Status padrão Por quê (e como é limitado quando ligado)
Prompt injection (direta/indireta) N/A desligado Sob --advice: conteúdo de finding é dado não-confiável delimitado; o system prompt proíbe tratá-lo como instrução
Jailbreak / bypass de system prompt N/A desligado Sob --advice: a saída é advisory-only e não pode alterar correlação/gate, então um bypass gera no máximo prosa ruim
Data poisoning (envenenamento de dados de treino) N/A O Quorum não treina nada; o corpus OWASP é pinado por digest e atestado
Model poisoning / supply chain de modelo N/A desligado Sob --advice: o artefato do modelo é dependência externa pinada pelo operador; nenhum modelo vem na imagem/binário
Hallucination (alucinação) N/A desligado Sob --advice: recomendações são advisory-only; todo patch sugerido precisa passar no re-scan verify-the-fix antes de ser mostrado
Insecure output handling N/A desligado Relatórios (SARIF/JSON/XML) são serialização estruturada; o texto de IA é um anexo rotulado e clampado que nunca dirige o gate
Sensitive information disclosure via modelo N/A desligado Local: nada sai da máquina. Remoto: só metadados de finding normalizado, gated em consentimento; segredos são redigidos nas saídas
Excessive agency (agência excessiva) N/A desligado Sob --advice: sem agente; a única ação é propor um patch, que nunca é aplicado automaticamente (verify-the-fix em cópia temporária)
Model denial of service / custo descontrolado N/A desligado Sob --advice: --advice-max limita findings; compute local é on-host; remoto é off por padrão. Caps de DoS de execução: QUORUM_MAX_OUTPUT_BYTES (512MiB), QUORUM_MAX_TARGET_BYTES (20GiB)

Riscos reais do Quorum (supply chain das imagens/binários dos scanners, over-merge de MISCONFIG, falsos negativos por mount malformado) são tratados fora desta seção — ver DESIGN §12 (supply chain), a §12-segurança e o README ("Known limitations", "Security of the chain itself"). Esses riscos são de software tradicional, não de IA.


5. Checklist de conformidade (estado atual — v0.8.3)

  • [x] Confirmado que o núcleo não importa LLM/provedor de IA (go.mod revisado: só cobra + yaml.v3; a camada consultiva fala com um endpoint externo via net/http).
  • [x] Confirmado que o caminho de decisão do núcleo não tem RAG/embeddings/vector DB; o RAG sob --advice é retrieval determinístico sobre um artefato pinado por digest (internal/rag).
  • [x] Confirmado que não há MCP/agentes/function-calling em lugar algum.
  • [x] Confirmado que não há runtime de inferência vendorado (sem ONNX/TF/PyTorch); um modelo local é servido pelo próprio endpoint do operador.
  • [x] Confirmado que os 12 adapters (internal/adapter) e o crosswalk (crosswalk/*.yaml) são regras determinísticas, sem ML.
  • [x] Confirmado que o único cliente de rede do núcleo é OSV.dev (internal/alias/osv.go).
  • [x] Confirmado que OSV.dev é desligável via --offline (modo air-gapped), o que também bloqueia o provedor consultivo remoto.
  • [x] Confirmado que a camada consultiva é opt-in e off por padrão; sem --advice o relatório é byte-idêntico ao de um build sem IA.
  • [x] Confirmado que nenhum código-fonte do usuário sai da máquina: advice local fica on-host; remoto envia só findings normalizados, é gated em consentimento (--advice-allow-egress) e recusa --fix.
  • [x] Confirmado que os evals (internal/evals) protegem a qualidade consultiva no CI (cobertura de remediação, relevância das referências OWASP, taxa de verify-the-fix).

6. A camada consultiva (implementada — claramente separada do núcleo)

Tudo nesta seção é presentational-only e off por padrão. Nunca toca o núcleo determinístico (correlação, fingerprint, confidence, severidade agregada ou o gate de fail-on). Sem --advice, nada disso executa.

📄 O design detalhado está em 21-proposta-ia.md — a camada consultiva opt-in (recomendações local-first, remediação em dois níveis com verify-the-fix, e RAG-as-artifact sobre um corpus OWASP pinado). As Fases 0–3 já estão implementadas.

As quatro fases, todas entregues na v0.8.3:

  1. Fase 0 — enriquecimento determinístico (sem modelo). Templates de remediação curados + referências OWASP, casados por canonicalControl/ruleId/category/type (pacote internal/enrich; dados em knowledge/*.yaml). Popula MergedFinding.Remediation e References.
  2. Fase 2 — RAG-as-artifact (determinístico). Retrieval de um corpus OWASP versionado e pinado por digest (knowledge/owasp/corpus.yaml, internal/rag). Léxico por padrão; semântico quando o corpus está embedado via quorum advise-index. Nunca gera texto — apenas recupera.
  3. Fase 1 — LLM local opt-in. --advice-provider=local consulta um endpoint OpenAI-compatible on-host para uma recomendação; --fix=suggest propõe um patch que precisa passar no re-scan verify-the-fix (aplicado a uma cópia temporária, re-scaneado com o mesmo scanner, mantido só se o finding sumiu e o arquivo ainda faz parse; nunca aplicado automaticamente). Reproduzível via temperature=0 + cache em disco chaveado por fingerprint+provider+model.
  4. Fase 3 — provedor remoto opt-in. --advice-provider=remote chama uma API externa (auth via QUORUM_ADVICE_API_KEY); gated em --advice-allow-egress, bloqueado por --offline, e recusa --fix. Só o finding normalizado é enviado.

Guardrails (aplicados em código):

Guardrail Regra
Opt-in explícito Toda a camada fica atrás de --advice, off por padrão
Núcleo intocável O LLM não pode alterar correlação, fingerprint, confidence ou exit code
Determinismo do gate A decisão de pass/fail permanece 100% determinística
Privacidade Local não envia nada para fora; remoto envia só findings normalizados, nunca código bruto, e só com consentimento
Modo offline --offline desabilita o provedor remoto (como já faz com o OSV)
Anti prompt-injection Conteúdo de findings é tratado como dado delimitado, não instrução
Rotulagem Toda saída gerada por modelo é marcada como "AI-generated, advisory only"
Auditabilidade Provider/modelo gravados em cada anexo; temperature=0 + cache para reprodutibilidade
Custo/limites Cap --advice-max, timeouts e fallback gracioso (mesma postura do cliente OSV)
Evals A suíte internal/evals protege a qualidade consultiva no CI antes do release

Premissas

  • A análise reflete o estado do repositório na v0.8.3, branch main, verificado via go.mod e busca textual por termos de IA em todo o código.
  • "OSV.dev" é tratado como serviço de dados determinístico (lookup de aliases), não como sistema de ML — consistente com internal/alias/osv.go e DESIGN §7.
  • O termo "orchestrator" no Quorum refere-se ao fan-out paralelo dos 12 scanners (internal/orchestrator), e não a um agente de IA; isso foi assumido pela ausência total de um modelo no caminho de decisão.
  • O crosswalk (crosswalk/*.yaml) é assumido como configuração de regras determinística derivada de output real dos scanners, não como classificador aprendido — consistente com os adapters em internal/adapter.
  • A camada consultiva é assumida como presentational-only e off por padrão; toda afirmação de "byte-idêntico sem --advice" é assumida como verdadeira porque os pacotes consultivos só são invocados quando a flag é passada.
  • Assumiu-se que fixtures de teste (internal/adapter/testdata/) não fazem parte do caminho de execução de produção (são dados de contract tests); a palavra "vector" que aparece neles refere-se a CVSS vector strings, não a embeddings.