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.moddeclara apenasgithub.com/spf13/cobraegopkg.in/yaml.v3como dependências diretas (maispflag/mousetrapindiretas). Nenhuma biblioteca de ML/LLM/vetorial está vendorada — a camada consultiva opt-in fala com um endpoint OpenAI-compatible externo vianet/httpe 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-ininternal/advisor,internal/rag,internal/enrich,internal/evalse a fixtures de teste. A palavra "vector" eminternal/adapter/testdata/sca_grype_alpine.jsonesca_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 sendointernal/alias/osv.go— umnet/httpGET contrahttps://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/<id><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.modrevisado: sócobra+yaml.v3; a camada consultiva fala com um endpoint externo vianet/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
--adviceo 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:
- Fase 0 — enriquecimento determinístico (sem modelo). Templates de
remediação curados + referências OWASP, casados por
canonicalControl/ruleId/category/type(pacoteinternal/enrich; dados emknowledge/*.yaml). PopulaMergedFinding.RemediationeReferences. - 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 viaquorum advise-index. Nunca gera texto — apenas recupera. - Fase 1 — LLM local opt-in.
--advice-provider=localconsulta um endpoint OpenAI-compatible on-host para uma recomendação;--fix=suggestpropõ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 viatemperature=0+ cache em disco chaveado porfingerprint+provider+model. - Fase 3 — provedor remoto opt-in.
--advice-provider=remotechama uma API externa (auth viaQUORUM_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 viago.mode 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.goeDESIGN §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 eminternal/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.